Просмотр исходного кода

Document RFC 8414 Support

Fixes gh-7462
Josh Cummings 6 лет назад
Родитель
Сommit
3a9ee46719

+ 7 - 3
docs/manual/src/docs/asciidoc/_includes/reactive/oauth2/login.adoc

@@ -89,7 +89,7 @@ At this point, the OAuth Client retrieves your email address and basic profile i
 == Using OpenID Provider Configuration
 
 For well known providers, Spring Security provides the necessary defaults for the OAuth Authorization Provider's configuration.
-If you are working with your own Authorization Provider that supports https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[OpenID Provider Configuration], you may use the https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse[OpenID Provider Configuration Response] the issuer-uri can be used to configure the application.
+If you are working with your own Authorization Provider that supports https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[OpenID Provider Configuration] or https://tools.ietf.org/html/rfc8414#section-3[Authorization Server Metadata], the https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse[OpenID Provider Configuration Response]'s `issuer-uri` can be used to configure the application.
 
 [source,yml]
 ----
@@ -106,7 +106,11 @@ spring:
             client-secret: 6cea952f-10d0-4d00-ac79-cc865820dc2c
 ----
 
-The `issuer-uri` instructs Spring Security to leverage the endpoint at `https://idp.example.com/auth/realms/demo/.well-known/openid-configuration` to discover the configuration.
+The `issuer-uri` instructs Spring Security to query in series the endpoints `https://idp.example.com/auth/realms/demo/.well-known/openid-configuration`, `https://idp.example.com/.well-known/openid-configuration/auth/realms/demo`, or `https://idp.example.com/.well-known/oauth-authorization-server/auth/realms/demo` to discover the configuration.
+
+[NOTE]
+Spring Security will query the endpoints one at a time, stopping at the first that gives a 200 response.
+
 The `client-id` and `client-secret` are linked to the provider because `keycloak` is used for both the provider and the registration.
 
 
@@ -120,7 +124,7 @@ A minimal OAuth2 Login configuration is shown below:
 @Bean
 ReactiveClientRegistrationRepository clientRegistrations() {
 	ClientRegistration clientRegistration = ClientRegistrations
-			.fromOidcIssuerLocation("https://idp.example.com/auth/realms/demo")
+			.fromIssuerLocation("https://idp.example.com/auth/realms/demo")
 			.clientId("spring-security")
 			.clientSecret("6cea952f-10d0-4d00-ac79-cc865820dc2c")
 			.build();

+ 14 - 11
docs/manual/src/docs/asciidoc/_includes/reactive/oauth2/resource-server.adoc

@@ -1,5 +1,5 @@
 [[webflux-oauth2-resource-server]]
-= OAuth2 Resource Server
+= OAuth 2.0 Resource Server
 
 Spring Security supports protecting endpoints using two forms of OAuth 2.0 https://tools.ietf.org/html/rfc6750.html[Bearer Tokens]:
 
@@ -36,15 +36,15 @@ spring:
     oauth2:
       resourceserver:
         jwt:
-          issuer-uri: https://idp.example.com
+          issuer-uri: https://idp.example.com/issuer
 ----
 
-Where `https://idp.example.com` is the value contained in the `iss` claim for JWT tokens that the authorization server will issue.
+Where `https://idp.example.com/issuer` is the value contained in the `iss` claim for JWT tokens that the authorization server will issue.
 Resource Server will use this property to further self-configure, discover the authorization server's public keys, and subsequently validate incoming JWTs.
 
 [NOTE]
-To use the `issuer-uri` property, it must also be true that `https://idp.example.com/.well-known/openid-configuration` is a supported endpoint for the authorization server.
-This endpoint is referred to as a https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Provider Configuration] endpoint.
+To use the `issuer-uri` property, it must also be true that one of `https://idp.example.com/issuer/.well-known/openid-configuration`, `https://idp.example.com/.well-known/openid-configuration/issuer`, or `https://idp.example.com/.well-known/oauth-authorization-server/issuer` is a supported endpoint for the authorization server.
+This endpoint is referred to as a https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Provider Configuration] endpoint or a https://tools.ietf.org/html/rfc8414#section-3[Authorization Server Metadata] endpoint.
 
 And that's it!
 
@@ -54,7 +54,7 @@ When this property and these dependencies are used, Resource Server will automat
 
 It achieves this through a deterministic startup process:
 
-1. Hit the Provider Configuration endpoint, `https://idp.example.com/.well-known/openid-configuration`, processing the response for the `jwks_url` property
+1. Hit the Provider Configuration or Authorization Server Metadata endpoint, processing the response for the `jwks_url` property
 2. Configure the validation strategy to query `jwks_url` for valid public keys
 3. Configure the validation strategy to validate each JWTs `iss` claim against `https://idp.example.com`.
 
@@ -95,7 +95,7 @@ From here, consider jumping to:
 [[webflux-oauth2resourceserver-jwt-jwkseturi]]
 === Specifying the Authorization Server JWK Set Uri Directly
 
-If the authorization server doesn't support the Provider Configuration endpoint, or if Resource Server must be able to start up independently from the authorization server, then `issuer-uri` can be exchanged for `jwk-set-uri`:
+If the authorization server doesn't support any configuration endpoints, or if Resource Server must be able to start up independently from the authorization server, then the `jwk-set-uri` can be supplied as well:
 
 [source,yaml]
 ----
@@ -104,6 +104,7 @@ spring:
     oauth2:
       resourceserver:
         jwt:
+          issuer-uri: https://idp.example.com
           jwk-set-uri: https://idp.example.com/.well-known/jwks.json
 ----
 
@@ -111,7 +112,7 @@ spring:
 The JWK Set uri is not standardized, but can typically be found in the authorization server's documentation
 
 Consequently, Resource Server will not ping the authorization server at startup.
-However, it will also no longer validate the `iss` claim in the JWT (since Resource Server no longer knows what the issuer value should be).
+We still specify the `issuer-uri` so that Resource Server still validates the `iss` claim on incoming JWTs.
 
 [NOTE]
 This property can also be supplied directly on the <<webflux-oauth2resourceserver-jwt-jwkseturi-dsl,DSL>>.
@@ -169,10 +170,12 @@ For example, the second `@Bean` Spring Boot creates is a `ReactiveJwtDecoder`, w
 ----
 @Bean
 public ReactiveJwtDecoder jwtDecoder() {
-    return ReactiveJwtDecoders.fromOidcIssuerLocation(issuerUri);
+    return ReactiveJwtDecoders.fromIssuerLocation(issuerUri);
 }
 ----
 
+[NOTE]
+Calling `{security-api-url}org/springframework/security/oauth2/jwt/ReactiveJwtDecoders.html#fromIssuerLocation-java.lang.String-[ReactiveJwtDecoders#fromIssuerLocation]` is what invokes the Provider Configuration or Authorization Server Metadata endpoint in order to derive the JWK Set Uri.
 If the application doesn't expose a `ReactiveJwtDecoder` bean, then Spring Boot will expose the above default one.
 
 And its configuration can be overridden using `jwkSetUri()` or replaced using `decoder()`.
@@ -494,7 +497,7 @@ Resource Server uses `JwtTimestampValidator` to verify a token's validity window
 @Bean
 ReactiveJwtDecoder jwtDecoder() {
      NimbusReactiveJwtDecoder jwtDecoder = (NimbusReactiveJwtDecoder)
-             ReactiveJwtDecoders.fromOidcIssuerLocation(issuerUri);
+             ReactiveJwtDecoders.fromIssuerLocation(issuerUri);
 
      OAuth2TokenValidator<Jwt> withClockSkew = new DelegatingOAuth2TokenValidator<>(
             new JwtTimestampValidator(Duration.ofSeconds(60)),
@@ -536,7 +539,7 @@ Then, to add into a resource server, it's a matter of specifying the `ReactiveJw
 @Bean
 ReactiveJwtDecoder jwtDecoder() {
     NimbusReactiveJwtDecoder jwtDecoder = (NimbusReactiveJwtDecoder)
-            ReactiveJwtDecoders.fromOidcIssuerLocation(issuerUri);
+            ReactiveJwtDecoders.fromIssuerLocation(issuerUri);
 
     OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator();
     OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);

+ 21 - 0
docs/manual/src/docs/asciidoc/_includes/servlet/preface/oauth2-client.adoc

@@ -75,6 +75,7 @@ The following sections will go into more detail on the core components used by O
 
 * <<oauth2Client-core-interface-class>>
 ** <<oauth2Client-client-registration, ClientRegistration>>
+** <<oauth2Client-client-registrations, ClientRegistrations>>
 ** <<oauth2Client-client-registration-repo, ClientRegistrationRepository>>
 ** <<oauth2Client-authorized-client, OAuth2AuthorizedClient>>
 ** <<oauth2Client-authorized-repo-service, OAuth2AuthorizedClientRepository / OAuth2AuthorizedClientService>>
@@ -153,6 +154,26 @@ The name may be used in certain scenarios, such as when displaying the name of t
 The supported values are *header*, *form* and *query*.
 <15> `userNameAttributeName`: The name of the attribute returned in the UserInfo Response that references the Name or Identifier of the end-user.
 
+[[oauth2Client-client-registrations]]
+==== ClientRegistrations
+
+A `ClientRegistration` can be initially configured by hitting an authorization server's https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Provider Configuration] endpoint or a https://tools.ietf.org/html/rfc8414#section-3[Authorization Server Metadata] endpoint.
+
+`ClientRegistrations` provides convenience methods for generating a `ClientRegistration` in this way, as can be seen in the following example:
+
+[source,java]
+----
+@Bean
+public ClientRegistrationRepository clientRegistrationRepository() {
+	ClientRegistration clientRegistration =
+	    ClientRegistrations.fromIssuerLocation("https://idp.example.com/issuer").build();
+	return new InMemoryClientRegistrationRepository(clientRegistration);
+}
+----
+
+The above code will query in series `https://idp.example.com/issuer/.well-known/openid-configuration`, and then `https://idp.example.com/.well-known/openid-configuration/issuer`, and finally `https://idp.example.com/.well-known/oauth-authorization-server/issuer`, stopping at the first to return a 200 response.
+
+As an alternative, you can invoke `ClientRegistrations#fromOidcIssuerLocation` to only hit the OIDC Provider Configuration endpoint.
 
 [[oauth2Client-client-registration-repo]]
 ==== ClientRegistrationRepository

+ 14 - 10
docs/manual/src/docs/asciidoc/_includes/servlet/preface/oauth2-resourceserver.adoc

@@ -36,15 +36,15 @@ spring:
     oauth2:
       resourceserver:
         jwt:
-          issuer-uri: https://idp.example.com
+          issuer-uri: https://idp.example.com/issuer
 ----
 
-Where `https://idp.example.com` is the value contained in the `iss` claim for JWT tokens that the authorization server will issue.
+Where `https://idp.example.com/issuer` is the value contained in the `iss` claim for JWT tokens that the authorization server will issue.
 Resource Server will use this property to further self-configure, discover the authorization server's public keys, and subsequently validate incoming JWTs.
 
 [NOTE]
-To use the `issuer-uri` property, it must also be true that `https://idp.example.com/.well-known/openid-configuration` is a supported endpoint for the authorization server.
-This endpoint is referred to as a https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Provider Configuration] endpoint.
+To use the `issuer-uri` property, it must also be true that one of `https://idp.example.com/issuer/.well-known/openid-configuration`, `https://idp.example.com/.well-known/openid-configuration/issuer`, or `https://idp.example.com/.well-known/oauth-authorization-server/issuer` is a supported endpoint for the authorization server.
+This endpoint is referred to as a https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Provider Configuration] endpoint or a https://tools.ietf.org/html/rfc8414#section-3[Authorization Server Metadata] endpoint.
 
 And that's it!
 
@@ -54,7 +54,7 @@ When this property and these dependencies are used, Resource Server will automat
 
 It achieves this through a deterministic startup process:
 
-1. Hit the Provider Configuration endpoint, `https://idp.example.com/.well-known/openid-configuration`, processing the response for the `jwks_url` property
+1. Hit the Provider Configuration or Authorization Server Metadata endpoint, processing the response for the `jwks_url` property
 2. Configure the validation strategy to query `jwks_url` for valid public keys
 3. Configure the validation strategy to validate each JWTs `iss` claim against `https://idp.example.com`.
 
@@ -95,7 +95,7 @@ From here, consider jumping to:
 [[oauth2resourceserver-jwt-jwkseturi]]
 === Specifying the Authorization Server JWK Set Uri Directly
 
-If the authorization server doesn't support the Provider Configuration endpoint, or if Resource Server must be able to start up independently from the authorization server, then `issuer-uri` can be exchanged for `jwk-set-uri`:
+If the authorization server doesn't support any configuration endpoints, or if Resource Server must be able to start up independently from the authorization server, then the `jwk-set-uri` can be supplied as well:
 
 [source,yaml]
 ----
@@ -104,6 +104,7 @@ spring:
     oauth2:
       resourceserver:
         jwt:
+          issuer-uri: https://idp.example.com
           jwk-set-uri: https://idp.example.com/.well-known/jwks.json
 ----
 
@@ -111,7 +112,7 @@ spring:
 The JWK Set uri is not standardized, but can typically be found in the authorization server's documentation
 
 Consequently, Resource Server will not ping the authorization server at startup.
-However, it will also no longer validate the `iss` claim in the JWT (since Resource Server no longer knows what the issuer value should be).
+We still specify the `issuer-uri` so that Resource Server still validates the `iss` claim on incoming JWTs.
 
 [NOTE]
 This property can also be supplied directly on the <<oauth2resourceserver-jwt-jwkseturi-dsl,DSL>>.
@@ -165,10 +166,13 @@ For example, the second `@Bean` Spring Boot creates is a `JwtDecoder`, which dec
 ----
 @Bean
 public JwtDecoder jwtDecoder() {
-    return JwtDecoders.fromOidcIssuerLocation(issuerUri);
+    return JwtDecoders.fromIssuerLocation(issuerUri);
 }
 ----
 
+[NOTE]
+Calling `{security-api-url}org/springframework/security/oauth2/jwt/JwtDecoders.html#fromIssuerLocation-java.lang.String-[JwtDecoders#fromIssuerLocation]` is what invokes the Provider Configuration or Authorization Server Metadata endpoint in order to derive the JWK Set Uri.
+
 If the application doesn't expose a `JwtDecoder` bean, then Spring Boot will expose the above default one.
 
 And its configuration can be overridden using `jwkSetUri()` or replaced using `decoder()`.
@@ -512,7 +516,7 @@ Resource Server uses `JwtTimestampValidator` to verify a token's validity window
 @Bean
 JwtDecoder jwtDecoder() {
      NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder)
-             JwtDecoders.fromOidcIssuerLocation(issuerUri);
+             JwtDecoders.fromIssuerLocation(issuerUri);
 
      OAuth2TokenValidator<Jwt> withClockSkew = new DelegatingOAuth2TokenValidator<>(
             new JwtTimestampValidator(Duration.ofSeconds(60)),
@@ -554,7 +558,7 @@ Then, to add into a resource server, it's a matter of specifying the `JwtDecoder
 @Bean
 JwtDecoder jwtDecoder() {
     NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder)
-        JwtDecoders.fromOidcIssuerLocation(issuerUri);
+        JwtDecoders.fromIssuerLocation(issuerUri);
 
     OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator();
     OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);