Skip to content

Commit 3a9ee46

Browse files
committed
Document RFC 8414 Support
Fixes gh-7462
1 parent b91668a commit 3a9ee46

File tree

4 files changed

+56
-24
lines changed

4 files changed

+56
-24
lines changed

docs/manual/src/docs/asciidoc/_includes/reactive/oauth2/login.adoc

+7-3
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ At this point, the OAuth Client retrieves your email address and basic profile i
8989
== Using OpenID Provider Configuration
9090

9191
For well known providers, Spring Security provides the necessary defaults for the OAuth Authorization Provider's configuration.
92-
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.
92+
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.
9393

9494
[source,yml]
9595
----
@@ -106,7 +106,11 @@ spring:
106106
client-secret: 6cea952f-10d0-4d00-ac79-cc865820dc2c
107107
----
108108

109-
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.
109+
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.
110+
111+
[NOTE]
112+
Spring Security will query the endpoints one at a time, stopping at the first that gives a 200 response.
113+
110114
The `client-id` and `client-secret` are linked to the provider because `keycloak` is used for both the provider and the registration.
111115

112116

@@ -120,7 +124,7 @@ A minimal OAuth2 Login configuration is shown below:
120124
@Bean
121125
ReactiveClientRegistrationRepository clientRegistrations() {
122126
ClientRegistration clientRegistration = ClientRegistrations
123-
.fromOidcIssuerLocation("https://idp.example.com/auth/realms/demo")
127+
.fromIssuerLocation("https://idp.example.com/auth/realms/demo")
124128
.clientId("spring-security")
125129
.clientSecret("6cea952f-10d0-4d00-ac79-cc865820dc2c")
126130
.build();

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

+14-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[[webflux-oauth2-resource-server]]
2-
= OAuth2 Resource Server
2+
= OAuth 2.0 Resource Server
33

44
Spring Security supports protecting endpoints using two forms of OAuth 2.0 https://tools.ietf.org/html/rfc6750.html[Bearer Tokens]:
55

@@ -36,15 +36,15 @@ spring:
3636
oauth2:
3737
resourceserver:
3838
jwt:
39-
issuer-uri: https://idp.example.com
39+
issuer-uri: https://idp.example.com/issuer
4040
----
4141

42-
Where `https://idp.example.com` is the value contained in the `iss` claim for JWT tokens that the authorization server will issue.
42+
Where `https://idp.example.com/issuer` is the value contained in the `iss` claim for JWT tokens that the authorization server will issue.
4343
Resource Server will use this property to further self-configure, discover the authorization server's public keys, and subsequently validate incoming JWTs.
4444

4545
[NOTE]
46-
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.
47-
This endpoint is referred to as a https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Provider Configuration] endpoint.
46+
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.
47+
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.
4848

4949
And that's it!
5050

@@ -54,7 +54,7 @@ When this property and these dependencies are used, Resource Server will automat
5454

5555
It achieves this through a deterministic startup process:
5656

57-
1. Hit the Provider Configuration endpoint, `https://idp.example.com/.well-known/openid-configuration`, processing the response for the `jwks_url` property
57+
1. Hit the Provider Configuration or Authorization Server Metadata endpoint, processing the response for the `jwks_url` property
5858
2. Configure the validation strategy to query `jwks_url` for valid public keys
5959
3. Configure the validation strategy to validate each JWTs `iss` claim against `https://idp.example.com`.
6060

@@ -95,7 +95,7 @@ From here, consider jumping to:
9595
[[webflux-oauth2resourceserver-jwt-jwkseturi]]
9696
=== Specifying the Authorization Server JWK Set Uri Directly
9797

98-
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`:
98+
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:
9999

100100
[source,yaml]
101101
----
@@ -104,14 +104,15 @@ spring:
104104
oauth2:
105105
resourceserver:
106106
jwt:
107+
issuer-uri: https://idp.example.com
107108
jwk-set-uri: https://idp.example.com/.well-known/jwks.json
108109
----
109110

110111
[NOTE]
111112
The JWK Set uri is not standardized, but can typically be found in the authorization server's documentation
112113

113114
Consequently, Resource Server will not ping the authorization server at startup.
114-
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).
115+
We still specify the `issuer-uri` so that Resource Server still validates the `iss` claim on incoming JWTs.
115116

116117
[NOTE]
117118
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
169170
----
170171
@Bean
171172
public ReactiveJwtDecoder jwtDecoder() {
172-
return ReactiveJwtDecoders.fromOidcIssuerLocation(issuerUri);
173+
return ReactiveJwtDecoders.fromIssuerLocation(issuerUri);
173174
}
174175
----
175176

177+
[NOTE]
178+
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.
176179
If the application doesn't expose a `ReactiveJwtDecoder` bean, then Spring Boot will expose the above default one.
177180

178181
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
494497
@Bean
495498
ReactiveJwtDecoder jwtDecoder() {
496499
NimbusReactiveJwtDecoder jwtDecoder = (NimbusReactiveJwtDecoder)
497-
ReactiveJwtDecoders.fromOidcIssuerLocation(issuerUri);
500+
ReactiveJwtDecoders.fromIssuerLocation(issuerUri);
498501
499502
OAuth2TokenValidator<Jwt> withClockSkew = new DelegatingOAuth2TokenValidator<>(
500503
new JwtTimestampValidator(Duration.ofSeconds(60)),
@@ -536,7 +539,7 @@ Then, to add into a resource server, it's a matter of specifying the `ReactiveJw
536539
@Bean
537540
ReactiveJwtDecoder jwtDecoder() {
538541
NimbusReactiveJwtDecoder jwtDecoder = (NimbusReactiveJwtDecoder)
539-
ReactiveJwtDecoders.fromOidcIssuerLocation(issuerUri);
542+
ReactiveJwtDecoders.fromIssuerLocation(issuerUri);
540543
541544
OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator();
542545
OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);

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

+21
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ The following sections will go into more detail on the core components used by O
7575

7676
* <<oauth2Client-core-interface-class>>
7777
** <<oauth2Client-client-registration, ClientRegistration>>
78+
** <<oauth2Client-client-registrations, ClientRegistrations>>
7879
** <<oauth2Client-client-registration-repo, ClientRegistrationRepository>>
7980
** <<oauth2Client-authorized-client, OAuth2AuthorizedClient>>
8081
** <<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
153154
The supported values are *header*, *form* and *query*.
154155
<15> `userNameAttributeName`: The name of the attribute returned in the UserInfo Response that references the Name or Identifier of the end-user.
155156

157+
[[oauth2Client-client-registrations]]
158+
==== ClientRegistrations
159+
160+
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.
161+
162+
`ClientRegistrations` provides convenience methods for generating a `ClientRegistration` in this way, as can be seen in the following example:
163+
164+
[source,java]
165+
----
166+
@Bean
167+
public ClientRegistrationRepository clientRegistrationRepository() {
168+
ClientRegistration clientRegistration =
169+
ClientRegistrations.fromIssuerLocation("https://idp.example.com/issuer").build();
170+
return new InMemoryClientRegistrationRepository(clientRegistration);
171+
}
172+
----
173+
174+
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.
175+
176+
As an alternative, you can invoke `ClientRegistrations#fromOidcIssuerLocation` to only hit the OIDC Provider Configuration endpoint.
156177

157178
[[oauth2Client-client-registration-repo]]
158179
==== ClientRegistrationRepository

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

+14-10
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ spring:
3636
oauth2:
3737
resourceserver:
3838
jwt:
39-
issuer-uri: https://idp.example.com
39+
issuer-uri: https://idp.example.com/issuer
4040
----
4141

42-
Where `https://idp.example.com` is the value contained in the `iss` claim for JWT tokens that the authorization server will issue.
42+
Where `https://idp.example.com/issuer` is the value contained in the `iss` claim for JWT tokens that the authorization server will issue.
4343
Resource Server will use this property to further self-configure, discover the authorization server's public keys, and subsequently validate incoming JWTs.
4444

4545
[NOTE]
46-
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.
47-
This endpoint is referred to as a https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Provider Configuration] endpoint.
46+
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.
47+
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.
4848

4949
And that's it!
5050

@@ -54,7 +54,7 @@ When this property and these dependencies are used, Resource Server will automat
5454

5555
It achieves this through a deterministic startup process:
5656

57-
1. Hit the Provider Configuration endpoint, `https://idp.example.com/.well-known/openid-configuration`, processing the response for the `jwks_url` property
57+
1. Hit the Provider Configuration or Authorization Server Metadata endpoint, processing the response for the `jwks_url` property
5858
2. Configure the validation strategy to query `jwks_url` for valid public keys
5959
3. Configure the validation strategy to validate each JWTs `iss` claim against `https://idp.example.com`.
6060

@@ -95,7 +95,7 @@ From here, consider jumping to:
9595
[[oauth2resourceserver-jwt-jwkseturi]]
9696
=== Specifying the Authorization Server JWK Set Uri Directly
9797

98-
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`:
98+
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:
9999

100100
[source,yaml]
101101
----
@@ -104,14 +104,15 @@ spring:
104104
oauth2:
105105
resourceserver:
106106
jwt:
107+
issuer-uri: https://idp.example.com
107108
jwk-set-uri: https://idp.example.com/.well-known/jwks.json
108109
----
109110

110111
[NOTE]
111112
The JWK Set uri is not standardized, but can typically be found in the authorization server's documentation
112113

113114
Consequently, Resource Server will not ping the authorization server at startup.
114-
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).
115+
We still specify the `issuer-uri` so that Resource Server still validates the `iss` claim on incoming JWTs.
115116

116117
[NOTE]
117118
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
165166
----
166167
@Bean
167168
public JwtDecoder jwtDecoder() {
168-
return JwtDecoders.fromOidcIssuerLocation(issuerUri);
169+
return JwtDecoders.fromIssuerLocation(issuerUri);
169170
}
170171
----
171172

173+
[NOTE]
174+
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.
175+
172176
If the application doesn't expose a `JwtDecoder` bean, then Spring Boot will expose the above default one.
173177

174178
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
512516
@Bean
513517
JwtDecoder jwtDecoder() {
514518
NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder)
515-
JwtDecoders.fromOidcIssuerLocation(issuerUri);
519+
JwtDecoders.fromIssuerLocation(issuerUri);
516520
517521
OAuth2TokenValidator<Jwt> withClockSkew = new DelegatingOAuth2TokenValidator<>(
518522
new JwtTimestampValidator(Duration.ofSeconds(60)),
@@ -554,7 +558,7 @@ Then, to add into a resource server, it's a matter of specifying the `JwtDecoder
554558
@Bean
555559
JwtDecoder jwtDecoder() {
556560
NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder)
557-
JwtDecoders.fromOidcIssuerLocation(issuerUri);
561+
JwtDecoders.fromIssuerLocation(issuerUri);
558562
559563
OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator();
560564
OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);

0 commit comments

Comments
 (0)