Migrate docs to Antora
Issue gh-1295
This commit is contained in:
committed by
Steve Riesenberg
parent
ec3d4fa7e1
commit
0f0424ad2a
1
docs/modules/ROOT/examples/docs-src
Symbolic link
1
docs/modules/ROOT/examples/docs-src
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../src
|
||||
1
docs/modules/ROOT/examples/samples
Symbolic link
1
docs/modules/ROOT/examples/samples
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../../samples
|
||||
12
docs/modules/ROOT/nav.adoc
Normal file
12
docs/modules/ROOT/nav.adoc
Normal file
@@ -0,0 +1,12 @@
|
||||
* xref:index.adoc[]
|
||||
* xref:getting-help.adoc[]
|
||||
* xref:getting-started.adoc[]
|
||||
* xref:configuration-model.adoc[]
|
||||
* xref:core-model-components.adoc[]
|
||||
* xref:protocol-endpoints.adoc[]
|
||||
* xref:how-to.adoc[]
|
||||
** xref:guides/how-to-ext-grant-type.adoc[]
|
||||
** xref:guides/how-to-jpa.adoc[]
|
||||
** xref:guides/how-to-pkce.adoc[]
|
||||
** xref:guides/how-to-social-login.adoc[]
|
||||
** xref:guides/how-to-userinfo.adoc[]
|
||||
322
docs/modules/ROOT/pages/configuration-model.adoc
Normal file
322
docs/modules/ROOT/pages/configuration-model.adoc
Normal file
@@ -0,0 +1,322 @@
|
||||
[[configuration-model]]
|
||||
= Configuration Model
|
||||
|
||||
[[default-configuration]]
|
||||
== Default configuration
|
||||
|
||||
`OAuth2AuthorizationServerConfiguration` is a `@Configuration` that provides the minimal default configuration for an OAuth2 authorization server.
|
||||
|
||||
`OAuth2AuthorizationServerConfiguration` uses xref:configuration-model.adoc#customizing-the-configuration[`OAuth2AuthorizationServerConfigurer`] to apply the default configuration and registers a `SecurityFilterChain` `@Bean` composed of all the infrastructure components supporting an OAuth2 authorization server.
|
||||
|
||||
[TIP]
|
||||
`OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(HttpSecurity)` is a convenience (`static`) utility method that applies the default OAuth2 security configuration to `HttpSecurity`.
|
||||
|
||||
The OAuth2 authorization server `SecurityFilterChain` `@Bean` is configured with the following default protocol endpoints:
|
||||
|
||||
* xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[OAuth2 Authorization endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-device-authorization-endpoint[OAuth2 Device Authorization Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-device-verification-endpoint[OAuth2 Device Verification Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-token-endpoint[OAuth2 Token endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-token-introspection-endpoint[OAuth2 Token Introspection endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-token-revocation-endpoint[OAuth2 Token Revocation endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-authorization-server-metadata-endpoint[OAuth2 Authorization Server Metadata endpoint]
|
||||
* xref:protocol-endpoints.adoc#jwk-set-endpoint[JWK Set endpoint]
|
||||
|
||||
[NOTE]
|
||||
The JWK Set endpoint is configured *only* if a `JWKSource<SecurityContext>` `@Bean` is registered.
|
||||
|
||||
The following example shows how to use `OAuth2AuthorizationServerConfiguration` to apply the minimal default configuration:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Configuration
|
||||
@Import(OAuth2AuthorizationServerConfiguration.class)
|
||||
public class AuthorizationServerConfig {
|
||||
|
||||
@Bean
|
||||
public RegisteredClientRepository registeredClientRepository() {
|
||||
List<RegisteredClient> registrations = ...
|
||||
return new InMemoryRegisteredClientRepository(registrations);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JWKSource<SecurityContext> jwkSource() {
|
||||
RSAKey rsaKey = ...
|
||||
JWKSet jwkSet = new JWKSet(rsaKey);
|
||||
return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
[IMPORTANT]
|
||||
The https://datatracker.ietf.org/doc/html/rfc6749#section-4.1[authorization_code grant] requires the resource owner to be authenticated. Therefore, a user authentication mechanism *must* be configured in addition to the default OAuth2 security configuration.
|
||||
|
||||
https://openid.net/specs/openid-connect-core-1_0.html[OpenID Connect 1.0] is disabled in the default configuration. The following example shows how to enable OpenID Connect 1.0 by initializing the `OidcConfigurer`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
|
||||
|
||||
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
|
||||
.oidc(Customizer.withDefaults()); // Initialize `OidcConfigurer`
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
In addition to the default protocol endpoints, the OAuth2 authorization server `SecurityFilterChain` `@Bean` is configured with the following OpenID Connect 1.0 protocol endpoints:
|
||||
|
||||
* xref:protocol-endpoints.adoc#oidc-provider-configuration-endpoint[OpenID Connect 1.0 Provider Configuration endpoint]
|
||||
* xref:protocol-endpoints.adoc#oidc-logout-endpoint[OpenID Connect 1.0 Logout endpoint]
|
||||
* xref:protocol-endpoints.adoc#oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint]
|
||||
|
||||
[NOTE]
|
||||
The xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration endpoint] is disabled by default because many deployments do not require dynamic client registration.
|
||||
|
||||
[TIP]
|
||||
`OAuth2AuthorizationServerConfiguration.jwtDecoder(JWKSource<SecurityContext>)` is a convenience (`static`) utility method that can be used to register a `JwtDecoder` `@Bean`, which is *REQUIRED* for the xref:protocol-endpoints.adoc#oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint] and the xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration endpoint].
|
||||
|
||||
The following example shows how to register a `JwtDecoder` `@Bean`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
|
||||
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
|
||||
}
|
||||
----
|
||||
|
||||
The main intent of `OAuth2AuthorizationServerConfiguration` is to provide a convenient method to apply the minimal default configuration for an OAuth2 authorization server. However, in most cases, customizing the configuration will be required.
|
||||
|
||||
[[customizing-the-configuration]]
|
||||
== Customizing the configuration
|
||||
|
||||
`OAuth2AuthorizationServerConfigurer` provides the ability to fully customize the security configuration for an OAuth2 authorization server.
|
||||
It lets you specify the core components to use - for example, xref:core-model-components.adoc#registered-client-repository[`RegisteredClientRepository`], xref:core-model-components.adoc#oauth2-authorization-service[`OAuth2AuthorizationService`], xref:core-model-components.adoc#oauth2-token-generator[`OAuth2TokenGenerator`], and others.
|
||||
Furthermore, it lets you customize the request processing logic for the protocol endpoints – for example, xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[authorization endpoint], xref:protocol-endpoints.adoc#oauth2-device-authorization-endpoint[device authorization endpoint], xref:protocol-endpoints.adoc#oauth2-device-verification-endpoint[device verification endpoint], xref:protocol-endpoints.adoc#oauth2-token-endpoint[token endpoint], xref:protocol-endpoints.adoc#oauth2-token-introspection-endpoint[token introspection endpoint], and others.
|
||||
|
||||
`OAuth2AuthorizationServerConfigurer` provides the following configuration options:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.registeredClientRepository(registeredClientRepository) <1>
|
||||
.authorizationService(authorizationService) <2>
|
||||
.authorizationConsentService(authorizationConsentService) <3>
|
||||
.authorizationServerSettings(authorizationServerSettings) <4>
|
||||
.tokenGenerator(tokenGenerator) <5>
|
||||
.clientAuthentication(clientAuthentication -> { }) <6>
|
||||
.authorizationEndpoint(authorizationEndpoint -> { }) <7>
|
||||
.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint -> { }) <8>
|
||||
.deviceVerificationEndpoint(deviceVerificationEndpoint -> { }) <9>
|
||||
.tokenEndpoint(tokenEndpoint -> { }) <10>
|
||||
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint -> { }) <11>
|
||||
.tokenRevocationEndpoint(tokenRevocationEndpoint -> { }) <12>
|
||||
.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint -> { }) <13>
|
||||
.oidc(oidc -> oidc
|
||||
.providerConfigurationEndpoint(providerConfigurationEndpoint -> { }) <14>
|
||||
.logoutEndpoint(logoutEndpoint -> { }) <15>
|
||||
.userInfoEndpoint(userInfoEndpoint -> { }) <16>
|
||||
.clientRegistrationEndpoint(clientRegistrationEndpoint -> { }) <17>
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `registeredClientRepository()`: The xref:core-model-components.adoc#registered-client-repository[`RegisteredClientRepository`] (*REQUIRED*) for managing new and existing clients.
|
||||
<2> `authorizationService()`: The xref:core-model-components.adoc#oauth2-authorization-service[`OAuth2AuthorizationService`] for managing new and existing authorizations.
|
||||
<3> `authorizationConsentService()`: The xref:core-model-components.adoc#oauth2-authorization-consent-service[`OAuth2AuthorizationConsentService`] for managing new and existing authorization consents.
|
||||
<4> `authorizationServerSettings()`: The xref:configuration-model.adoc#configuring-authorization-server-settings[`AuthorizationServerSettings`] (*REQUIRED*) for customizing configuration settings for the OAuth2 authorization server.
|
||||
<5> `tokenGenerator()`: The xref:core-model-components.adoc#oauth2-token-generator[`OAuth2TokenGenerator`] for generating tokens supported by the OAuth2 authorization server.
|
||||
<6> `clientAuthentication()`: The configurer for xref:configuration-model.adoc#configuring-client-authentication[OAuth2 Client Authentication].
|
||||
<7> `authorizationEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[OAuth2 Authorization endpoint].
|
||||
<8> `deviceAuthorizationEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-device-authorization-endpoint[OAuth2 Device Authorization endpoint].
|
||||
<9> `deviceVerificationEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-device-verification-endpoint[OAuth2 Device Verification endpoint].
|
||||
<10> `tokenEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-token-endpoint[OAuth2 Token endpoint].
|
||||
<11> `tokenIntrospectionEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-token-introspection-endpoint[OAuth2 Token Introspection endpoint].
|
||||
<12> `tokenRevocationEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-token-revocation-endpoint[OAuth2 Token Revocation endpoint].
|
||||
<13> `authorizationServerMetadataEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oauth2-authorization-server-metadata-endpoint[OAuth2 Authorization Server Metadata endpoint].
|
||||
<14> `providerConfigurationEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oidc-provider-configuration-endpoint[OpenID Connect 1.0 Provider Configuration endpoint].
|
||||
<15> `logoutEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oidc-logout-endpoint[OpenID Connect 1.0 Logout endpoint].
|
||||
<16> `userInfoEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint].
|
||||
<17> `clientRegistrationEndpoint()`: The configurer for the xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration endpoint].
|
||||
|
||||
[[configuring-authorization-server-settings]]
|
||||
== Configuring Authorization Server Settings
|
||||
|
||||
`AuthorizationServerSettings` contains the configuration settings for the OAuth2 authorization server.
|
||||
It specifies the `URI` for the protocol endpoints as well as the https://datatracker.ietf.org/doc/html/rfc8414#section-2[issuer identifier].
|
||||
The default `URI` for the protocol endpoints are as follows:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
public final class AuthorizationServerSettings extends AbstractSettings {
|
||||
|
||||
...
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder()
|
||||
.authorizationEndpoint("/oauth2/authorize")
|
||||
.deviceAuthorizationEndpoint("/oauth2/device_authorization")
|
||||
.deviceVerificationEndpoint("/oauth2/device_verification")
|
||||
.tokenEndpoint("/oauth2/token")
|
||||
.tokenIntrospectionEndpoint("/oauth2/introspect")
|
||||
.tokenRevocationEndpoint("/oauth2/revoke")
|
||||
.jwkSetEndpoint("/oauth2/jwks")
|
||||
.oidcLogoutEndpoint("/connect/logout")
|
||||
.oidcUserInfoEndpoint("/userinfo")
|
||||
.oidcClientRegistrationEndpoint("/connect/register");
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
`AuthorizationServerSettings` is a *REQUIRED* component.
|
||||
|
||||
[TIP]
|
||||
xref:configuration-model.adoc#default-configuration[`@Import(OAuth2AuthorizationServerConfiguration.class)`] automatically registers an `AuthorizationServerSettings` `@Bean`, if not already provided.
|
||||
|
||||
The following example shows how to customize the configuration settings and register an `AuthorizationServerSettings` `@Bean`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public AuthorizationServerSettings authorizationServerSettings() {
|
||||
return AuthorizationServerSettings.builder()
|
||||
.issuer("https://example.com")
|
||||
.authorizationEndpoint("/oauth2/v1/authorize")
|
||||
.deviceAuthorizationEndpoint("/oauth2/v1/device_authorization")
|
||||
.deviceVerificationEndpoint("/oauth2/v1/device_verification")
|
||||
.tokenEndpoint("/oauth2/v1/token")
|
||||
.tokenIntrospectionEndpoint("/oauth2/v1/introspect")
|
||||
.tokenRevocationEndpoint("/oauth2/v1/revoke")
|
||||
.jwkSetEndpoint("/oauth2/v1/jwks")
|
||||
.oidcLogoutEndpoint("/connect/v1/logout")
|
||||
.oidcUserInfoEndpoint("/connect/v1/userinfo")
|
||||
.oidcClientRegistrationEndpoint("/connect/v1/register")
|
||||
.build();
|
||||
}
|
||||
----
|
||||
|
||||
The `AuthorizationServerContext` is a context object that holds information of the Authorization Server runtime environment.
|
||||
It provides access to the `AuthorizationServerSettings` and the "`current`" issuer identifier.
|
||||
|
||||
[NOTE]
|
||||
If the issuer identifier is not configured in `AuthorizationServerSettings.builder().issuer(String)`, it is resolved from the current request.
|
||||
|
||||
[NOTE]
|
||||
The `AuthorizationServerContext` is accessible through the `AuthorizationServerContextHolder`, which associates it with the current request thread by using a `ThreadLocal`.
|
||||
|
||||
[[configuring-client-authentication]]
|
||||
== Configuring Client Authentication
|
||||
|
||||
`OAuth2ClientAuthenticationConfigurer` provides the ability to customize https://datatracker.ietf.org/doc/html/rfc6749#section-2.3[OAuth2 client authentication].
|
||||
It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for client authentication requests.
|
||||
|
||||
`OAuth2ClientAuthenticationConfigurer` provides the following configuration options:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.clientAuthentication(clientAuthentication ->
|
||||
clientAuthentication
|
||||
.authenticationConverter(authenticationConverter) <1>
|
||||
.authenticationConverters(authenticationConvertersConsumer) <2>
|
||||
.authenticationProvider(authenticationProvider) <3>
|
||||
.authenticationProviders(authenticationProvidersConsumer) <4>
|
||||
.authenticationSuccessHandler(authenticationSuccessHandler) <5>
|
||||
.errorResponseHandler(errorResponseHandler) <6>
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `authenticationConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract client credentials from `HttpServletRequest` to an instance of `OAuth2ClientAuthenticationToken`.
|
||||
<2> `authenticationConverters()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationConverter``'s allowing the ability to add, remove, or customize a specific `AuthenticationConverter`.
|
||||
<3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2ClientAuthenticationToken`.
|
||||
<4> `authenticationProviders()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationProvider``'s allowing the ability to add, remove, or customize a specific `AuthenticationProvider`.
|
||||
<5> `authenticationSuccessHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling a successful client authentication and associating the `OAuth2ClientAuthenticationToken` to the `SecurityContext`.
|
||||
<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling a failed client authentication and returning the https://datatracker.ietf.org/doc/html/rfc6749#section-5.2[`OAuth2Error` response].
|
||||
|
||||
`OAuth2ClientAuthenticationConfigurer` configures the `OAuth2ClientAuthenticationFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`OAuth2ClientAuthenticationFilter` is the `Filter` that processes client authentication requests.
|
||||
|
||||
By default, client authentication is required for the xref:protocol-endpoints.adoc#oauth2-token-endpoint[OAuth2 Token endpoint], the xref:protocol-endpoints.adoc#oauth2-token-introspection-endpoint[OAuth2 Token Introspection endpoint], and the xref:protocol-endpoints.adoc#oauth2-token-revocation-endpoint[OAuth2 Token Revocation endpoint].
|
||||
The supported client authentication methods are `client_secret_basic`, `client_secret_post`, `private_key_jwt`, `client_secret_jwt`, and `none` (public clients).
|
||||
|
||||
`OAuth2ClientAuthenticationFilter` is configured with the following defaults:
|
||||
|
||||
* `*AuthenticationConverter*` -- A `DelegatingAuthenticationConverter` composed of `JwtClientAssertionAuthenticationConverter`, `ClientSecretBasicAuthenticationConverter`, `ClientSecretPostAuthenticationConverter`, and `PublicClientAuthenticationConverter`.
|
||||
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `JwtClientAssertionAuthenticationProvider`, `ClientSecretAuthenticationProvider`, and `PublicClientAuthenticationProvider`.
|
||||
* `*AuthenticationSuccessHandler*` -- An internal implementation that associates the "`authenticated`" `OAuth2ClientAuthenticationToken` (current `Authentication`) to the `SecurityContext`.
|
||||
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` to return the OAuth2 error response.
|
||||
|
||||
[[configuring-client-authentication-customizing-jwt-client-assertion-validation]]
|
||||
=== Customizing Jwt Client Assertion Validation
|
||||
|
||||
`JwtClientAssertionDecoderFactory.DEFAULT_JWT_VALIDATOR_FACTORY` is the default factory that provides an `OAuth2TokenValidator<Jwt>` for the specified `RegisteredClient` and is used for validating the `iss`, `sub`, `aud`, `exp` and `nbf` claims of the `Jwt` client assertion.
|
||||
|
||||
`JwtClientAssertionDecoderFactory` provides the ability to override the default `Jwt` client assertion validation by supplying a custom factory of type `Function<RegisteredClient, OAuth2TokenValidator<Jwt>>` to `setJwtValidatorFactory()`.
|
||||
|
||||
[NOTE]
|
||||
`JwtClientAssertionDecoderFactory` is the default `JwtDecoderFactory` used by `JwtClientAssertionAuthenticationProvider` that provides a `JwtDecoder` for the specified `RegisteredClient` and is used for authenticating a `Jwt` Bearer Token during OAuth2 client authentication.
|
||||
|
||||
A common use case for customizing `JwtClientAssertionDecoderFactory` is to validate additional claims in the `Jwt` client assertion.
|
||||
|
||||
The following example shows how to configure `JwtClientAssertionAuthenticationProvider` with a customized `JwtClientAssertionDecoderFactory` that validates an additional claim in the `Jwt` client assertion:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.clientAuthentication(clientAuthentication ->
|
||||
clientAuthentication
|
||||
.authenticationProviders(configureJwtClientAssertionValidator())
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
private Consumer<List<AuthenticationProvider>> configureJwtClientAssertionValidator() {
|
||||
return (authenticationProviders) ->
|
||||
authenticationProviders.forEach((authenticationProvider) -> {
|
||||
if (authenticationProvider instanceof JwtClientAssertionAuthenticationProvider) {
|
||||
// Customize JwtClientAssertionDecoderFactory
|
||||
JwtClientAssertionDecoderFactory jwtDecoderFactory = new JwtClientAssertionDecoderFactory();
|
||||
Function<RegisteredClient, OAuth2TokenValidator<Jwt>> jwtValidatorFactory = (registeredClient) ->
|
||||
new DelegatingOAuth2TokenValidator<>(
|
||||
// Use default validators
|
||||
JwtClientAssertionDecoderFactory.DEFAULT_JWT_VALIDATOR_FACTORY.apply(registeredClient),
|
||||
// Add custom validator
|
||||
new JwtClaimValidator<>("claim", "value"::equals));
|
||||
jwtDecoderFactory.setJwtValidatorFactory(jwtValidatorFactory);
|
||||
|
||||
((JwtClientAssertionAuthenticationProvider) authenticationProvider)
|
||||
.setJwtDecoderFactory(jwtDecoderFactory);
|
||||
}
|
||||
});
|
||||
}
|
||||
----
|
||||
526
docs/modules/ROOT/pages/core-model-components.adoc
Normal file
526
docs/modules/ROOT/pages/core-model-components.adoc
Normal file
@@ -0,0 +1,526 @@
|
||||
[[core-model-components]]
|
||||
= Core Model / Components
|
||||
|
||||
[[registered-client]]
|
||||
== RegisteredClient
|
||||
|
||||
A `RegisteredClient` is a representation of a client that is https://datatracker.ietf.org/doc/html/rfc6749#section-2[registered] with the authorization server.
|
||||
A client must be registered with the authorization server before it can initiate an authorization grant flow, such as `authorization_code` or `client_credentials`.
|
||||
|
||||
During client registration, the client is assigned a unique https://datatracker.ietf.org/doc/html/rfc6749#section-2.2[client identifier], (optionally) a client secret (depending on https://datatracker.ietf.org/doc/html/rfc6749#section-2.1[client type]), and metadata associated with its unique client identifier.
|
||||
The client's metadata can range from human-facing display strings (such as client name) to items specific to a protocol flow (such as the list of valid redirect URIs).
|
||||
|
||||
[TIP]
|
||||
The corresponding client registration model in Spring Security's OAuth2 Client support is {spring-security-reference-base-url}/servlet/oauth2/client/core.html#oauth2Client-client-registration[ClientRegistration].
|
||||
|
||||
The primary purpose of a client is to request access to protected resources.
|
||||
The client first requests an access token by authenticating with the authorization server and presenting the authorization grant.
|
||||
The authorization server authenticates the client and authorization grant, and, if they are valid, issues an access token.
|
||||
The client can now request the protected resource from the resource server by presenting the access token.
|
||||
|
||||
The following example shows how to configure a `RegisteredClient` that is allowed to perform the https://datatracker.ietf.org/doc/html/rfc6749#section-4.1[authorization_code grant] flow to request an access token:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
|
||||
.clientId("client-a")
|
||||
.clientSecret("{noop}secret") <1>
|
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
|
||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
|
||||
.redirectUri("http://127.0.0.1:8080/authorized")
|
||||
.scope("scope-a")
|
||||
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
|
||||
.build();
|
||||
----
|
||||
<1> `\{noop\}` represents the `PasswordEncoder` id for Spring Security's {spring-security-reference-base-url}/features/authentication/password-storage.html#authentication-password-storage-dpe[NoOpPasswordEncoder].
|
||||
|
||||
The corresponding configuration in Spring Security's {spring-security-reference-base-url}/servlet/oauth2/client/index.html[OAuth2 Client support] is:
|
||||
|
||||
[source,yaml]
|
||||
----
|
||||
spring:
|
||||
security:
|
||||
oauth2:
|
||||
client:
|
||||
registration:
|
||||
client-a:
|
||||
provider: spring
|
||||
client-id: client-a
|
||||
client-secret: secret
|
||||
authorization-grant-type: authorization_code
|
||||
redirect-uri: "http://127.0.0.1:8080/authorized"
|
||||
scope: scope-a
|
||||
provider:
|
||||
spring:
|
||||
issuer-uri: http://localhost:9000
|
||||
----
|
||||
|
||||
A `RegisteredClient` has metadata (attributes) associated with its unique Client Identifier and is defined as follows:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
public class RegisteredClient implements Serializable {
|
||||
private String id; <1>
|
||||
private String clientId; <2>
|
||||
private Instant clientIdIssuedAt; <3>
|
||||
private String clientSecret; <4>
|
||||
private Instant clientSecretExpiresAt; <5>
|
||||
private String clientName; <6>
|
||||
private Set<ClientAuthenticationMethod> clientAuthenticationMethods; <7>
|
||||
private Set<AuthorizationGrantType> authorizationGrantTypes; <8>
|
||||
private Set<String> redirectUris; <9>
|
||||
private Set<String> postLogoutRedirectUris; <10>
|
||||
private Set<String> scopes; <11>
|
||||
private ClientSettings clientSettings; <12>
|
||||
private TokenSettings tokenSettings; <13>
|
||||
|
||||
...
|
||||
|
||||
}
|
||||
----
|
||||
<1> `id`: The ID that uniquely identifies the `RegisteredClient`.
|
||||
<2> `clientId`: The client identifier.
|
||||
<3> `clientIdIssuedAt`: The time at which the client identifier was issued.
|
||||
<4> `clientSecret`: The client's secret. The value should be encoded using Spring Security's {spring-security-reference-base-url}/features/authentication/password-storage.html#authentication-password-storage-dpe[PasswordEncoder].
|
||||
<5> `clientSecretExpiresAt`: The time at which the client secret expires.
|
||||
<6> `clientName`: A descriptive name used for the client. The name may be used in certain scenarios, such as when displaying the client name in the consent page.
|
||||
<7> `clientAuthenticationMethods`: The authentication method(s) that the client may use. The supported values are `client_secret_basic`, `client_secret_post`, https://datatracker.ietf.org/doc/html/rfc7523[`private_key_jwt`], `client_secret_jwt`, and `none` https://datatracker.ietf.org/doc/html/rfc7636[(public clients)].
|
||||
<8> `authorizationGrantTypes`: The https://datatracker.ietf.org/doc/html/rfc6749#section-1.3[authorization grant type(s)] that the client can use. The supported values are `authorization_code`, `client_credentials`, `refresh_token`, and `urn:ietf:params:oauth:grant-type:device_code`.
|
||||
<9> `redirectUris`: The registered https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2[redirect URI(s)] that the client may use in redirect-based flows – for example, `authorization_code` grant.
|
||||
<10> `postLogoutRedirectUris`: The post logout redirect URI(s) that the client may use for logout.
|
||||
<11> `scopes`: The scope(s) that the client is allowed to request.
|
||||
<12> `clientSettings`: The custom settings for the client – for example, require https://datatracker.ietf.org/doc/html/rfc7636[PKCE], require authorization consent, and others.
|
||||
<13> `tokenSettings`: The custom settings for the OAuth2 tokens issued to the client – for example, access/refresh token time-to-live, reuse refresh tokens, and others.
|
||||
|
||||
[[registered-client-repository]]
|
||||
== RegisteredClientRepository
|
||||
|
||||
The `RegisteredClientRepository` is the central component where new clients can be registered and existing clients can be queried.
|
||||
It is used by other components when following a specific protocol flow, such as client authentication, authorization grant processing, token introspection, dynamic client registration, and others.
|
||||
|
||||
The provided implementations of `RegisteredClientRepository` are `InMemoryRegisteredClientRepository` and `JdbcRegisteredClientRepository`.
|
||||
The `InMemoryRegisteredClientRepository` implementation stores `RegisteredClient` instances in-memory and is recommended *ONLY* to be used during development and testing.
|
||||
`JdbcRegisteredClientRepository` is a JDBC implementation that persists `RegisteredClient` instances by using `JdbcOperations`.
|
||||
|
||||
[NOTE]
|
||||
The `RegisteredClientRepository` is a *REQUIRED* component.
|
||||
|
||||
The following example shows how to register a `RegisteredClientRepository` `@Bean`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public RegisteredClientRepository registeredClientRepository() {
|
||||
List<RegisteredClient> registrations = ...
|
||||
return new InMemoryRegisteredClientRepository(registrations);
|
||||
}
|
||||
----
|
||||
|
||||
Alternatively, you can configure the `RegisteredClientRepository` through the xref:configuration-model.adoc#customizing-the-configuration[`OAuth2AuthorizationServerConfigurer`]:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.registeredClientRepository(registeredClientRepository);
|
||||
|
||||
...
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
The `OAuth2AuthorizationServerConfigurer` is useful when applying multiple configuration options simultaneously.
|
||||
|
||||
[[oauth2-authorization]]
|
||||
== OAuth2Authorization
|
||||
|
||||
An `OAuth2Authorization` is a representation of an OAuth2 authorization, which holds state related to the authorization granted to a xref:core-model-components.adoc#registered-client[client], by the resource owner or itself in the case of the `client_credentials` authorization grant type.
|
||||
|
||||
[TIP]
|
||||
The corresponding authorization model in Spring Security's OAuth2 Client support is {spring-security-reference-base-url}/servlet/oauth2/client/core.html#oauth2Client-authorized-client[OAuth2AuthorizedClient].
|
||||
|
||||
After the successful completion of an authorization grant flow, an `OAuth2Authorization` is created and associates an {spring-security-api-base-url}/org/springframework/security/oauth2/core/OAuth2AccessToken.html[`OAuth2AccessToken`], an (optional) {spring-security-api-base-url}/org/springframework/security/oauth2/core/OAuth2RefreshToken.html[`OAuth2RefreshToken`], and additional state specific to the executed authorization grant type.
|
||||
|
||||
The {spring-security-api-base-url}/org/springframework/security/oauth2/core/OAuth2Token.html[`OAuth2Token`] instances associated with an `OAuth2Authorization` vary, depending on the authorization grant type.
|
||||
|
||||
For the OAuth2 https://datatracker.ietf.org/doc/html/rfc6749#section-4.1[authorization_code grant], an `OAuth2AuthorizationCode`, an `OAuth2AccessToken`, and an (optional) `OAuth2RefreshToken` are associated.
|
||||
|
||||
For the OpenID Connect 1.0 https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[authorization_code grant], an `OAuth2AuthorizationCode`, an {spring-security-api-base-url}/org/springframework/security/oauth2/core/oidc/OidcIdToken.html[`OidcIdToken`], an `OAuth2AccessToken`, and an (optional) `OAuth2RefreshToken` are associated.
|
||||
|
||||
For the OAuth2 https://datatracker.ietf.org/doc/html/rfc6749#section-4.4[client_credentials grant], only an `OAuth2AccessToken` is associated.
|
||||
|
||||
`OAuth2Authorization` and its attributes are defined as follows:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
public class OAuth2Authorization implements Serializable {
|
||||
private String id; <1>
|
||||
private String registeredClientId; <2>
|
||||
private String principalName; <3>
|
||||
private AuthorizationGrantType authorizationGrantType; <4>
|
||||
private Set<String> authorizedScopes; <5>
|
||||
private Map<Class<? extends OAuth2Token>, Token<?>> tokens; <6>
|
||||
private Map<String, Object> attributes; <7>
|
||||
|
||||
...
|
||||
|
||||
}
|
||||
----
|
||||
<1> `id`: The ID that uniquely identifies the `OAuth2Authorization`.
|
||||
<2> `registeredClientId`: The ID that uniquely identifies the xref:core-model-components.adoc#registered-client[RegisteredClient].
|
||||
<3> `principalName`: The principal name of the resource owner (or client).
|
||||
<4> `authorizationGrantType`: The `AuthorizationGrantType` used.
|
||||
<5> `authorizedScopes`: The `Set` of scope(s) authorized for the client.
|
||||
<6> `tokens`: The `OAuth2Token` instances (and associated metadata) specific to the executed authorization grant type.
|
||||
<7> `attributes`: The additional attributes specific to the executed authorization grant type – for example, the authenticated `Principal`, `OAuth2AuthorizationRequest`, and others.
|
||||
|
||||
`OAuth2Authorization` and its associated `OAuth2Token` instances have a set lifespan.
|
||||
A newly issued `OAuth2Token` is active and becomes inactive when it either expires or is invalidated (revoked).
|
||||
The `OAuth2Authorization` is (implicitly) inactive when all associated `OAuth2Token` instances are inactive.
|
||||
Each `OAuth2Token` is held in an `OAuth2Authorization.Token`, which provides accessors for `isExpired()`, `isInvalidated()`, and `isActive()`.
|
||||
|
||||
`OAuth2Authorization.Token` also provides `getClaims()`, which returns the claims (if any) associated with the `OAuth2Token`.
|
||||
|
||||
[[oauth2-authorization-service]]
|
||||
== OAuth2AuthorizationService
|
||||
|
||||
The `OAuth2AuthorizationService` is the central component where new authorizations are stored and existing authorizations are queried.
|
||||
It is used by other components when following a specific protocol flow – for example, client authentication, authorization grant processing, token introspection, token revocation, dynamic client registration, and others.
|
||||
|
||||
The provided implementations of `OAuth2AuthorizationService` are `InMemoryOAuth2AuthorizationService` and `JdbcOAuth2AuthorizationService`.
|
||||
The `InMemoryOAuth2AuthorizationService` implementation stores `OAuth2Authorization` instances in-memory and is recommended *ONLY* to be used during development and testing.
|
||||
`JdbcOAuth2AuthorizationService` is a JDBC implementation that persists `OAuth2Authorization` instances by using `JdbcOperations`.
|
||||
|
||||
[NOTE]
|
||||
The `OAuth2AuthorizationService` is an *OPTIONAL* component and defaults to `InMemoryOAuth2AuthorizationService`.
|
||||
|
||||
The following example shows how to register an `OAuth2AuthorizationService` `@Bean`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public OAuth2AuthorizationService authorizationService() {
|
||||
return new InMemoryOAuth2AuthorizationService();
|
||||
}
|
||||
----
|
||||
|
||||
Alternatively, you can configure the `OAuth2AuthorizationService` through the xref:configuration-model.adoc#customizing-the-configuration[`OAuth2AuthorizationServerConfigurer`]:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.authorizationService(authorizationService);
|
||||
|
||||
...
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
The `OAuth2AuthorizationServerConfigurer` is useful when applying multiple configuration options simultaneously.
|
||||
|
||||
[[oauth2-authorization-consent]]
|
||||
== OAuth2AuthorizationConsent
|
||||
|
||||
An `OAuth2AuthorizationConsent` is a representation of an authorization "consent" (decision) from an https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1[OAuth2 authorization request flow] – for example, the `authorization_code` grant, which holds the authorities granted to a xref:core-model-components.adoc#registered-client[client] by the resource owner.
|
||||
|
||||
When authorizing access to a client, the resource owner may grant only a subset of the authorities requested by the client.
|
||||
The typical use case is the `authorization_code` grant flow, in which the client requests scope(s) and the resource owner grants (or denies) access to the requested scope(s).
|
||||
|
||||
After the completion of an OAuth2 authorization request flow, an `OAuth2AuthorizationConsent` is created (or updated) and associates the granted authorities with the client and resource owner.
|
||||
|
||||
`OAuth2AuthorizationConsent` and its attributes are defined as follows:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
public final class OAuth2AuthorizationConsent implements Serializable {
|
||||
private final String registeredClientId; <1>
|
||||
private final String principalName; <2>
|
||||
private final Set<GrantedAuthority> authorities; <3>
|
||||
|
||||
...
|
||||
|
||||
}
|
||||
----
|
||||
<1> `registeredClientId`: The ID that uniquely identifies the xref:core-model-components.adoc#registered-client[RegisteredClient].
|
||||
<2> `principalName`: The principal name of the resource owner.
|
||||
<3> `authorities`: The authorities granted to the client by the resource owner. An authority can represent a scope, a claim, a permission, a role, and others.
|
||||
|
||||
[[oauth2-authorization-consent-service]]
|
||||
== OAuth2AuthorizationConsentService
|
||||
|
||||
The `OAuth2AuthorizationConsentService` is the central component where new authorization consents are stored and existing authorization consents are queried.
|
||||
It is primarily used by components that implement an OAuth2 authorization request flow – for example, the `authorization_code` grant.
|
||||
|
||||
The provided implementations of `OAuth2AuthorizationConsentService` are `InMemoryOAuth2AuthorizationConsentService` and `JdbcOAuth2AuthorizationConsentService`.
|
||||
The `InMemoryOAuth2AuthorizationConsentService` implementation stores `OAuth2AuthorizationConsent` instances in-memory and is recommended *ONLY* for development and testing.
|
||||
`JdbcOAuth2AuthorizationConsentService` is a JDBC implementation that persists `OAuth2AuthorizationConsent` instances by using `JdbcOperations`.
|
||||
|
||||
[NOTE]
|
||||
The `OAuth2AuthorizationConsentService` is an *OPTIONAL* component and defaults to `InMemoryOAuth2AuthorizationConsentService`.
|
||||
|
||||
The following example shows how to register an `OAuth2AuthorizationConsentService` `@Bean`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public OAuth2AuthorizationConsentService authorizationConsentService() {
|
||||
return new InMemoryOAuth2AuthorizationConsentService();
|
||||
}
|
||||
----
|
||||
|
||||
Alternatively, you can configure the `OAuth2AuthorizationConsentService` through the xref:configuration-model.adoc#customizing-the-configuration[`OAuth2AuthorizationServerConfigurer`]:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.authorizationConsentService(authorizationConsentService);
|
||||
|
||||
...
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
The `OAuth2AuthorizationServerConfigurer` is useful when applying multiple configuration options simultaneously.
|
||||
|
||||
[[oauth2-token-context]]
|
||||
== OAuth2TokenContext
|
||||
|
||||
An `OAuth2TokenContext` is a context object that holds information associated with an `OAuth2Token` and is used by an xref:core-model-components.adoc#oauth2-token-generator[OAuth2TokenGenerator] and xref:core-model-components.adoc#oauth2-token-customizer[OAuth2TokenCustomizer].
|
||||
|
||||
`OAuth2TokenContext` provides the following accessors:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
public interface OAuth2TokenContext extends Context {
|
||||
|
||||
default RegisteredClient getRegisteredClient() ... <1>
|
||||
|
||||
default <T extends Authentication> T getPrincipal() ... <2>
|
||||
|
||||
default AuthorizationServerContext getAuthorizationServerContext() ... <3>
|
||||
|
||||
@Nullable
|
||||
default OAuth2Authorization getAuthorization() ... <4>
|
||||
|
||||
default Set<String> getAuthorizedScopes() ... <5>
|
||||
|
||||
default OAuth2TokenType getTokenType() ... <6>
|
||||
|
||||
default AuthorizationGrantType getAuthorizationGrantType() ... <7>
|
||||
|
||||
default <T extends Authentication> T getAuthorizationGrant() ... <8>
|
||||
|
||||
...
|
||||
|
||||
}
|
||||
----
|
||||
<1> `getRegisteredClient()`: The xref:core-model-components.adoc#registered-client[RegisteredClient] associated with the authorization grant.
|
||||
<2> `getPrincipal()`: The `Authentication` instance of the resource owner (or client).
|
||||
<3> `getAuthorizationServerContext()`: The xref:configuration-model.adoc#configuring-authorization-server-settings[`AuthorizationServerContext`] object that holds information of the Authorization Server runtime environment.
|
||||
<4> `getAuthorization()`: The xref:core-model-components.adoc#oauth2-authorization[OAuth2Authorization] associated with the authorization grant.
|
||||
<5> `getAuthorizedScopes()`: The scope(s) authorized for the client.
|
||||
<6> `getTokenType()`: The `OAuth2TokenType` to generate. The supported values are `code`, `access_token`, `refresh_token`, and `id_token`.
|
||||
<7> `getAuthorizationGrantType()`: The `AuthorizationGrantType` associated with the authorization grant.
|
||||
<8> `getAuthorizationGrant()`: The `Authentication` instance used by the `AuthenticationProvider` that processes the authorization grant.
|
||||
|
||||
[[oauth2-token-generator]]
|
||||
== OAuth2TokenGenerator
|
||||
|
||||
An `OAuth2TokenGenerator` is responsible for generating an `OAuth2Token` from the information contained in the provided xref:core-model-components.adoc#oauth2-token-context[OAuth2TokenContext].
|
||||
|
||||
The `OAuth2Token` generated primarily depends on the type of `OAuth2TokenType` specified in the `OAuth2TokenContext`.
|
||||
|
||||
For example, when the `value` for `OAuth2TokenType` is:
|
||||
|
||||
* `code`, then `OAuth2AuthorizationCode` is generated.
|
||||
* `access_token`, then `OAuth2AccessToken` is generated.
|
||||
* `refresh_token`, then `OAuth2RefreshToken` is generated.
|
||||
* `id_token`, then `OidcIdToken` is generated.
|
||||
|
||||
Furthermore, the format of the generated `OAuth2AccessToken` varies, depending on the `TokenSettings.getAccessTokenFormat()` configured for the xref:core-model-components.adoc#registered-client[RegisteredClient].
|
||||
If the format is `OAuth2TokenFormat.SELF_CONTAINED` (the default), then a `Jwt` is generated.
|
||||
If the format is `OAuth2TokenFormat.REFERENCE`, then an "opaque" token is generated.
|
||||
|
||||
Finally, if the generated `OAuth2Token` has a set of claims and implements `ClaimAccessor`, the claims are made accessible from xref:core-model-components.adoc#oauth2-authorization[OAuth2Authorization.Token.getClaims()].
|
||||
|
||||
The `OAuth2TokenGenerator` is primarily used by components that implement authorization grant processing – for example, `authorization_code`, `client_credentials`, and `refresh_token`.
|
||||
|
||||
The provided implementations are `OAuth2AccessTokenGenerator`, `OAuth2RefreshTokenGenerator`, and `JwtGenerator`.
|
||||
The `OAuth2AccessTokenGenerator` generates an "opaque" (`OAuth2TokenFormat.REFERENCE`) access token, and the `JwtGenerator` generates a `Jwt` (`OAuth2TokenFormat.SELF_CONTAINED`).
|
||||
|
||||
[NOTE]
|
||||
The `OAuth2TokenGenerator` is an *OPTIONAL* component and defaults to a `DelegatingOAuth2TokenGenerator` composed of an `OAuth2AccessTokenGenerator` and `OAuth2RefreshTokenGenerator`.
|
||||
|
||||
[NOTE]
|
||||
If a `JwtEncoder` `@Bean` or `JWKSource<SecurityContext>` `@Bean` is registered, then a `JwtGenerator` is additionally composed in the `DelegatingOAuth2TokenGenerator`.
|
||||
|
||||
The `OAuth2TokenGenerator` provides great flexibility, as it can support any custom token format for `access_token` and `refresh_token`.
|
||||
|
||||
The following example shows how to register an `OAuth2TokenGenerator` `@Bean`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public OAuth2TokenGenerator<?> tokenGenerator() {
|
||||
JwtEncoder jwtEncoder = ...
|
||||
JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder);
|
||||
OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator();
|
||||
OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator();
|
||||
return new DelegatingOAuth2TokenGenerator(
|
||||
jwtGenerator, accessTokenGenerator, refreshTokenGenerator);
|
||||
}
|
||||
----
|
||||
|
||||
Alternatively, you can configure the `OAuth2TokenGenerator` through the xref:configuration-model.adoc#customizing-the-configuration[`OAuth2AuthorizationServerConfigurer`]:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.tokenGenerator(tokenGenerator);
|
||||
|
||||
...
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
The `OAuth2AuthorizationServerConfigurer` is useful when applying multiple configuration options simultaneously.
|
||||
|
||||
[[oauth2-token-customizer]]
|
||||
== OAuth2TokenCustomizer
|
||||
|
||||
An `OAuth2TokenCustomizer` provides the ability to customize the attributes of an `OAuth2Token`, which are accessible in the provided xref:core-model-components.adoc#oauth2-token-context[OAuth2TokenContext].
|
||||
It is used by an xref:core-model-components.adoc#oauth2-token-generator[OAuth2TokenGenerator] to let it customize the attributes of the `OAuth2Token` before it is generated.
|
||||
|
||||
An `OAuth2TokenCustomizer<OAuth2TokenClaimsContext>` declared with a generic type of `OAuth2TokenClaimsContext` (`implements OAuth2TokenContext`) provides the ability to customize the claims of an "opaque" `OAuth2AccessToken`.
|
||||
`OAuth2TokenClaimsContext.getClaims()` provides access to the `OAuth2TokenClaimsSet.Builder`, allowing the ability to add, replace, and remove claims.
|
||||
|
||||
The following example shows how to implement an `OAuth2TokenCustomizer<OAuth2TokenClaimsContext>` and configure it with an `OAuth2AccessTokenGenerator`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public OAuth2TokenGenerator<?> tokenGenerator() {
|
||||
JwtEncoder jwtEncoder = ...
|
||||
JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder);
|
||||
OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator();
|
||||
accessTokenGenerator.setAccessTokenCustomizer(accessTokenCustomizer());
|
||||
OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator();
|
||||
return new DelegatingOAuth2TokenGenerator(
|
||||
jwtGenerator, accessTokenGenerator, refreshTokenGenerator);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OAuth2TokenCustomizer<OAuth2TokenClaimsContext> accessTokenCustomizer() {
|
||||
return context -> {
|
||||
OAuth2TokenClaimsSet.Builder claims = context.getClaims();
|
||||
// Customize claims
|
||||
|
||||
};
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
If the `OAuth2TokenGenerator` is not provided as a `@Bean` or is not configured through the `OAuth2AuthorizationServerConfigurer`, an `OAuth2TokenCustomizer<OAuth2TokenClaimsContext>` `@Bean` will automatically be configured with an `OAuth2AccessTokenGenerator`.
|
||||
|
||||
An `OAuth2TokenCustomizer<JwtEncodingContext>` declared with a generic type of `JwtEncodingContext` (`implements OAuth2TokenContext`) provides the ability to customize the headers and claims of a `Jwt`.
|
||||
`JwtEncodingContext.getHeaders()` provides access to the `JwsHeader.Builder`, allowing the ability to add, replace, and remove headers.
|
||||
`JwtEncodingContext.getClaims()` provides access to the `JwtClaimsSet.Builder`, allowing the ability to add, replace, and remove claims.
|
||||
|
||||
The following example shows how to implement an `OAuth2TokenCustomizer<JwtEncodingContext>` and configure it with a `JwtGenerator`:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public OAuth2TokenGenerator<?> tokenGenerator() {
|
||||
JwtEncoder jwtEncoder = ...
|
||||
JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder);
|
||||
jwtGenerator.setJwtCustomizer(jwtCustomizer());
|
||||
OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator();
|
||||
OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator();
|
||||
return new DelegatingOAuth2TokenGenerator(
|
||||
jwtGenerator, accessTokenGenerator, refreshTokenGenerator);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OAuth2TokenCustomizer<JwtEncodingContext> jwtCustomizer() {
|
||||
return context -> {
|
||||
JwsHeader.Builder headers = context.getHeaders();
|
||||
JwtClaimsSet.Builder claims = context.getClaims();
|
||||
if (context.getTokenType().equals(OAuth2TokenType.ACCESS_TOKEN)) {
|
||||
// Customize headers/claims for access_token
|
||||
|
||||
} else if (context.getTokenType().getValue().equals(OidcParameterNames.ID_TOKEN)) {
|
||||
// Customize headers/claims for id_token
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
If the `OAuth2TokenGenerator` is not provided as a `@Bean` or is not configured through the `OAuth2AuthorizationServerConfigurer`, an `OAuth2TokenCustomizer<JwtEncodingContext>` `@Bean` will automatically be configured with a `JwtGenerator`.
|
||||
|
||||
[TIP]
|
||||
For an example showing how you can xref:guides/how-to-userinfo.adoc#customize-id-token[customize the ID token], see the guide xref:guides/how-to-userinfo.adoc[How-to: Customize the OpenID Connect 1.0 UserInfo response].
|
||||
|
||||
[[session-registry]]
|
||||
== SessionRegistry
|
||||
|
||||
If OpenID Connect 1.0 is enabled, a `SessionRegistry` instance is used to track authenticated sessions.
|
||||
The `SessionRegistry` is used by the default implementation of `SessionAuthenticationStrategy` associated to the xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[OAuth2 Authorization Endpoint] for registering new authenticated sessions.
|
||||
|
||||
[NOTE]
|
||||
If a `SessionRegistry` `@Bean` is not registered, the default implementation `SessionRegistryImpl` will be used.
|
||||
|
||||
[IMPORTANT]
|
||||
If a `SessionRegistry` `@Bean` is registered and is an instance of `SessionRegistryImpl`, a `HttpSessionEventPublisher` `@Bean` *SHOULD* also be registered as it's responsible for notifying `SessionRegistryImpl` of session lifecycle events, for example, `SessionDestroyedEvent`, to provide the ability to remove the `SessionInformation` instance.
|
||||
|
||||
When a logout is requested by an End-User, the xref:protocol-endpoints.adoc#oidc-logout-endpoint[OpenID Connect 1.0 Logout Endpoint] uses the `SessionRegistry` to lookup the `SessionInformation` associated to the authenticated End-User to perform the logout.
|
||||
|
||||
If Spring Security's {spring-security-reference-base-url}/servlet/authentication/session-management.html#ns-concurrent-sessions[Concurrent Session Control] feature is being used, it is *RECOMMENDED* to register a `SessionRegistry` `@Bean` to ensure it's shared between Spring Security's Concurrent Session Control and Spring Authorization Server's Logout feature.
|
||||
|
||||
The following example shows how to register a `SessionRegistry` `@Bean` and `HttpSessionEventPublisher` `@Bean` (required by `SessionRegistryImpl`):
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SessionRegistry sessionRegistry() {
|
||||
return new SessionRegistryImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HttpSessionEventPublisher httpSessionEventPublisher() {
|
||||
return new HttpSessionEventPublisher();
|
||||
}
|
||||
----
|
||||
24
docs/modules/ROOT/pages/getting-help.adoc
Normal file
24
docs/modules/ROOT/pages/getting-help.adoc
Normal file
@@ -0,0 +1,24 @@
|
||||
[[getting-help]]
|
||||
= Getting Help
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
[[community]]
|
||||
== Community
|
||||
|
||||
Welcome to the https://docs.spring.io/spring-security/reference/community.html[Spring Security Community].
|
||||
Spring Authorization Server is an open source project led by the Spring Security team.
|
||||
If you need help with Spring Authorization Server, we are here to help.
|
||||
|
||||
[[resources]]
|
||||
== Resources
|
||||
|
||||
The following are some of the best ways to get help:
|
||||
|
||||
* Try the xref:how-to.adoc[How-to guides]. They provide solutions to the most common questions.
|
||||
* Learn the Spring Security basics that Spring Authorization Server builds on. If you are starting out with Spring Security, check the https://spring.io/projects/spring-security#learn[reference documentation] or try one of the https://github.com/spring-projects/spring-security-samples[samples].
|
||||
* Read through xref:index.adoc[this documentation].
|
||||
* Try one of our many https://github.com/spring-projects/spring-authorization-server/tree/main/samples[sample applications].
|
||||
* Ask a question on Stack Overflow with the https://stackoverflow.com/questions/tagged/spring-authorization-server[`spring-authorization-server`] tag.
|
||||
* Report bugs and enhancement requests on https://github.com/spring-projects/spring-authorization-server/issues[GitHub].
|
||||
|
||||
NOTE: Spring Authorization Server is open source, including the documentation. If you find problems with the docs or if you want to improve them, please https://github.com/spring-projects/spring-authorization-server[get involved].
|
||||
107
docs/modules/ROOT/pages/getting-started.adoc
Normal file
107
docs/modules/ROOT/pages/getting-started.adoc
Normal file
@@ -0,0 +1,107 @@
|
||||
|
||||
[[getting-started]]
|
||||
= Getting Started
|
||||
|
||||
If you are just getting started with Spring Authorization Server, the following sections walk you through creating your first application.
|
||||
|
||||
[[system-requirements]]
|
||||
== System Requirements
|
||||
|
||||
Spring Authorization Server requires a Java 17 or higher Runtime Environment.
|
||||
|
||||
[[installing-spring-authorization-server]]
|
||||
== Installing Spring Authorization Server
|
||||
|
||||
Spring Authorization Server can be used anywhere you already use https://docs.spring.io/spring-security/reference/prerequisites.html[Spring Security].
|
||||
|
||||
The easiest way to begin using Spring Authorization Server is by creating a https://spring.io/projects/spring-boot[Spring Boot]-based application.
|
||||
You can use https://start.spring.io[start.spring.io] to generate a basic project or use the https://github.com/spring-projects/spring-authorization-server/tree/main/samples/default-authorizationserver[default authorization server sample] as a guide.
|
||||
Then add Spring Boot's starter for Spring Authorization Server as a dependency:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Maven::
|
||||
+
|
||||
[[spring-boot-maven-dependency]]
|
||||
[source,xml,role="primary",subs="attributes,verbatim"]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
Gradle::
|
||||
+
|
||||
[[spring-boot-gradle-dependency]]
|
||||
[source,gradle,role="secondary",subs="attributes,verbatim"]
|
||||
----
|
||||
implementation "org.springframework.boot:spring-boot-starter-oauth2-authorization-server"
|
||||
----
|
||||
======
|
||||
|
||||
TIP: See https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started.installing[Installing Spring Boot] for more information on using Spring Boot with Maven or Gradle.
|
||||
|
||||
Alternatively, you can add Spring Authorization Server without Spring Boot using the following example:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Maven::
|
||||
+
|
||||
[[maven-dependency]]
|
||||
[source,xml,role="primary",subs="attributes,verbatim"]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-oauth2-authorization-server</artifactId>
|
||||
<version>{spring-authorization-server-version}</version>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
Gradle::
|
||||
+
|
||||
[[gradle-dependency]]
|
||||
[source,gradle,role="secondary",subs="attributes,verbatim"]
|
||||
----
|
||||
implementation "org.springframework.security:spring-security-oauth2-authorization-server:{spring-authorization-server-version}"
|
||||
----
|
||||
======
|
||||
|
||||
[[developing-your-first-application]]
|
||||
== Developing Your First Application
|
||||
|
||||
To get started, you need the minimum required components defined as a `@Bean`. When using the `spring-boot-starter-oauth2-authorization-server` dependency, define the following properties and Spring Boot will provide the necessary `@Bean` definitions for you:
|
||||
|
||||
[[application-yml]]
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
include::{docs-java}/sample/gettingstarted/application.yml[]
|
||||
----
|
||||
|
||||
TIP: Beyond the Getting Started experience, most users will want to customize the default configuration. The xref:getting-started.adoc#defining-required-components[next section] demonstrates providing all of the necessary beans yourself.
|
||||
|
||||
[[defining-required-components]]
|
||||
== Defining Required Components
|
||||
|
||||
If you want to customize the default configuration (regardless of whether you're using Spring Boot), you can define the minimum required components as a `@Bean` in a Spring `@Configuration`.
|
||||
|
||||
These components can be defined as follows:
|
||||
|
||||
[[sample.gettingStarted]]
|
||||
.SecurityConfig.java
|
||||
[source,java]
|
||||
----
|
||||
include::{docs-java}/sample/gettingstarted/SecurityConfig.java[]
|
||||
----
|
||||
|
||||
This is a minimal configuration for getting started quickly. To understand what each component is used for, see the following descriptions:
|
||||
|
||||
<1> A Spring Security filter chain for the xref:protocol-endpoints.adoc[Protocol Endpoints].
|
||||
<2> A Spring Security filter chain for https://docs.spring.io/spring-security/reference/servlet/authentication/index.html[authentication].
|
||||
<3> An instance of {spring-security-api-base-url}/org/springframework/security/core/userdetails/UserDetailsService.html[`UserDetailsService`] for retrieving users to authenticate.
|
||||
<4> An instance of xref:core-model-components.adoc#registered-client-repository[`RegisteredClientRepository`] for managing clients.
|
||||
<5> An instance of `com.nimbusds.jose.jwk.source.JWKSource` for signing access tokens.
|
||||
<6> An instance of `java.security.KeyPair` with keys generated on startup used to create the `JWKSource` above.
|
||||
<7> An instance of {spring-security-api-base-url}/org/springframework/security/oauth2/jwt/JwtDecoder.html[`JwtDecoder`] for decoding signed access tokens.
|
||||
<8> An instance of xref:configuration-model#configuring-authorization-server-settings[`AuthorizationServerSettings`] to configure Spring Authorization Server.
|
||||
76
docs/modules/ROOT/pages/guides/how-to-ext-grant-type.adoc
Normal file
76
docs/modules/ROOT/pages/guides/how-to-ext-grant-type.adoc
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
[[how-to-extension-grant-type]]
|
||||
= How-to: Implement an Extension Authorization Grant Type
|
||||
:index-link: ../how-to.html
|
||||
:docs-dir: ..
|
||||
|
||||
This guide shows how to extend xref:index.adoc[Spring Authorization Server] with an https://datatracker.ietf.org/doc/html/rfc6749#section-4.5[extension authorization grant type].
|
||||
The purpose of this guide is to demonstrate how to implement an extension authorization grant type and configure it at the xref:protocol-endpoints.adoc#oauth2-token-endpoint[OAuth2 Token endpoint].
|
||||
|
||||
Extending Spring Authorization Server with a new authorization grant type requires implementing an `AuthenticationConverter` and `AuthenticationProvider`, and configuring both components at the xref:protocol-endpoints.adoc#oauth2-token-endpoint[OAuth2 Token endpoint].
|
||||
In addition to the component implementations, a unique absolute URI needs to be assigned for use with the `grant_type` parameter.
|
||||
|
||||
* xref:guides/how-to-ext-grant-type.adoc#implement-authentication-converter[Implement AuthenticationConverter]
|
||||
* xref:guides/how-to-ext-grant-type.adoc#implement-authentication-provider[Implement AuthenticationProvider]
|
||||
* xref:guides/how-to-ext-grant-type.adoc#configure-token-endpoint[Configure OAuth2 Token Endpoint]
|
||||
* xref:guides/how-to-ext-grant-type.adoc#request-access-token[Request the Access Token]
|
||||
|
||||
[[implement-authentication-converter]]
|
||||
== Implement AuthenticationConverter
|
||||
|
||||
Assuming the absolute URI for the `grant_type` parameter is `urn:ietf:params:oauth:grant-type:custom_code` and the `code` parameter represents the authorization grant, the following example shows a sample implementation of the `AuthenticationConverter`:
|
||||
|
||||
.AuthenticationConverter
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/extgrant/CustomCodeGrantAuthenticationConverter.java[]
|
||||
----
|
||||
|
||||
TIP: Click on the "Expand folded text" icon in the code sample above to display the full example.
|
||||
|
||||
<1> If the `grant_type` parameter is *not* `urn:ietf:params:oauth:grant-type:custom_code`, then return `null`, allowing another `AuthenticationConverter` to process the token request.
|
||||
<2> The `code` parameter contains the authorization grant.
|
||||
<3> Return an instance of `CustomCodeGrantAuthenticationToken`, which is processed by xref:guides/how-to-ext-grant-type.adoc#implement-authentication-provider[`CustomCodeGrantAuthenticationProvider`].
|
||||
|
||||
[[implement-authentication-provider]]
|
||||
== Implement AuthenticationProvider
|
||||
|
||||
The `AuthenticationProvider` implementation is responsible for validating the authorization grant, and if valid and authorized, issues an access token.
|
||||
|
||||
The following example shows a sample implementation of the `AuthenticationProvider`:
|
||||
|
||||
.AuthenticationProvider
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/extgrant/CustomCodeGrantAuthenticationProvider.java[]
|
||||
----
|
||||
|
||||
NOTE: `CustomCodeGrantAuthenticationProvider` processes `CustomCodeGrantAuthenticationToken`, which is created by xref:guides/how-to-ext-grant-type.adoc#implement-authentication-converter[`CustomCodeGrantAuthenticationConverter`].
|
||||
|
||||
[[configure-token-endpoint]]
|
||||
== Configure OAuth2 Token Endpoint
|
||||
|
||||
The following example shows how to configure the xref:protocol-endpoints.adoc#oauth2-token-endpoint[OAuth2 Token endpoint] with the `AuthenticationConverter` and `AuthenticationProvider`:
|
||||
|
||||
.SecurityConfig
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/extgrant/SecurityConfig.java[]
|
||||
----
|
||||
|
||||
<1> Add the `AuthenticationConverter` to the OAuth2 Token endpoint configuration.
|
||||
<2> Add the `AuthenticationProvider` to the OAuth2 Token endpoint configuration.
|
||||
|
||||
[[request-access-token]]
|
||||
== Request the Access Token
|
||||
|
||||
The client can request the access token by making the following (authenticated) request to the OAuth2 Token endpoint:
|
||||
|
||||
[source,shell]
|
||||
----
|
||||
POST /oauth2/token HTTP/1.1
|
||||
Authorization: Basic bWVzc2FnaW5nLWNsaWVudDpzZWNyZXQ=
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
grant_type=urn:ietf:params:oauth:grant-type:custom_code&code=7QR49T1W3
|
||||
----
|
||||
271
docs/modules/ROOT/pages/guides/how-to-jpa.adoc
Normal file
271
docs/modules/ROOT/pages/guides/how-to-jpa.adoc
Normal file
@@ -0,0 +1,271 @@
|
||||
|
||||
[[how-to-jpa]]
|
||||
= How-to: Implement core services with JPA
|
||||
:index-link: ../how-to.html
|
||||
:docs-dir: ..
|
||||
|
||||
This guide shows how to implement the xref:core-model-components.adoc[core services] of xref:index.adoc[Spring Authorization Server] with JPA.
|
||||
The purpose of this guide is to provide a starting point for implementing these services yourself, with the intention that you can make modifications to suit your needs.
|
||||
|
||||
* xref:guides/how-to-jpa.adoc#define-data-model[Define the data model]
|
||||
* xref:guides/how-to-jpa.adoc#create-jpa-entities[Create JPA entities]
|
||||
* xref:guides/how-to-jpa.adoc#create-spring-data-repositories[Create Spring Data repositories]
|
||||
* xref:guides/how-to-jpa.adoc#implement-core-services[Implement core services]
|
||||
|
||||
[[define-data-model]]
|
||||
== Define the data model
|
||||
|
||||
This guide provides a starting point for the data model and uses the simplest possible structure and data types.
|
||||
To come up with the initial schema, we begin by reviewing the xref:core-model-components.adoc[domain objects] used by the core services.
|
||||
|
||||
[NOTE]
|
||||
Except for token, state, metadata, settings, and claims values, we use the JPA default column length of 255 for all columns.
|
||||
In reality, the length and even type of columns you use may need to be customized.
|
||||
You are encouraged to experiment and test before deploying to production.
|
||||
|
||||
* xref:guides/how-to-jpa.adoc#client-schema[Client Schema]
|
||||
* xref:guides/how-to-jpa.adoc#authorization-schema[Authorization Schema]
|
||||
* xref:guides/how-to-jpa.adoc#authorization-consent-schema[Authorization Consent Schema]
|
||||
|
||||
[[client-schema]]
|
||||
=== Client Schema
|
||||
|
||||
The xref:core-model-components.adoc#registered-client[`RegisteredClient`] domain object contains a few multi-valued fields and some settings fields that require storing arbitrary key/value data.
|
||||
The following listing shows the `client` schema.
|
||||
|
||||
.Client Schema
|
||||
[source,sql]
|
||||
----
|
||||
CREATE TABLE client (
|
||||
id varchar(255) NOT NULL,
|
||||
clientId varchar(255) NOT NULL,
|
||||
clientIdIssuedAt timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
clientSecret varchar(255) DEFAULT NULL,
|
||||
clientSecretExpiresAt timestamp DEFAULT NULL,
|
||||
clientName varchar(255) NOT NULL,
|
||||
clientAuthenticationMethods varchar(1000) NOT NULL,
|
||||
authorizationGrantTypes varchar(1000) NOT NULL,
|
||||
redirectUris varchar(1000) DEFAULT NULL,
|
||||
postLogoutRedirectUris varchar(1000) DEFAULT NULL,
|
||||
scopes varchar(1000) NOT NULL,
|
||||
clientSettings varchar(2000) NOT NULL,
|
||||
tokenSettings varchar(2000) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
----
|
||||
|
||||
[[authorization-schema]]
|
||||
=== Authorization Schema
|
||||
|
||||
The xref:core-model-components.adoc#oauth2-authorization[`OAuth2Authorization`] domain object is more complex and contains several multi-valued fields as well as numerous arbitrarily long token values, metadata, settings and claims values.
|
||||
The built-in JDBC implementation utilizes a flattened structure that prefers performance over normalization, which we adopt here as well.
|
||||
|
||||
[CAUTION]
|
||||
It has been difficult to find a flattened database schema that works well in all cases and with all database vendors.
|
||||
You may need to normalize or heavily alter the following schema for your needs.
|
||||
|
||||
The following listing shows the `authorization` schema.
|
||||
|
||||
.Authorization Schema
|
||||
[source,sql]
|
||||
----
|
||||
CREATE TABLE authorization (
|
||||
id varchar(255) NOT NULL,
|
||||
registeredClientId varchar(255) NOT NULL,
|
||||
principalName varchar(255) NOT NULL,
|
||||
authorizationGrantType varchar(255) NOT NULL,
|
||||
authorizedScopes varchar(1000) DEFAULT NULL,
|
||||
attributes varchar(4000) DEFAULT NULL,
|
||||
state varchar(500) DEFAULT NULL,
|
||||
authorizationCodeValue varchar(4000) DEFAULT NULL,
|
||||
authorizationCodeIssuedAt timestamp DEFAULT NULL,
|
||||
authorizationCodeExpiresAt timestamp DEFAULT NULL,
|
||||
authorizationCodeMetadata varchar(2000) DEFAULT NULL,
|
||||
accessTokenValue varchar(4000) DEFAULT NULL,
|
||||
accessTokenIssuedAt timestamp DEFAULT NULL,
|
||||
accessTokenExpiresAt timestamp DEFAULT NULL,
|
||||
accessTokenMetadata varchar(2000) DEFAULT NULL,
|
||||
accessTokenType varchar(255) DEFAULT NULL,
|
||||
accessTokenScopes varchar(1000) DEFAULT NULL,
|
||||
refreshTokenValue varchar(4000) DEFAULT NULL,
|
||||
refreshTokenIssuedAt timestamp DEFAULT NULL,
|
||||
refreshTokenExpiresAt timestamp DEFAULT NULL,
|
||||
refreshTokenMetadata varchar(2000) DEFAULT NULL,
|
||||
oidcIdTokenValue varchar(4000) DEFAULT NULL,
|
||||
oidcIdTokenIssuedAt timestamp DEFAULT NULL,
|
||||
oidcIdTokenExpiresAt timestamp DEFAULT NULL,
|
||||
oidcIdTokenMetadata varchar(2000) DEFAULT NULL,
|
||||
oidcIdTokenClaims varchar(2000) DEFAULT NULL,
|
||||
userCodeValue varchar(4000) DEFAULT NULL,
|
||||
userCodeIssuedAt timestamp DEFAULT NULL,
|
||||
userCodeExpiresAt timestamp DEFAULT NULL,
|
||||
userCodeMetadata varchar(2000) DEFAULT NULL,
|
||||
deviceCodeValue varchar(4000) DEFAULT NULL,
|
||||
deviceCodeIssuedAt timestamp DEFAULT NULL,
|
||||
deviceCodeExpiresAt timestamp DEFAULT NULL,
|
||||
deviceCodeMetadata varchar(2000) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
----
|
||||
|
||||
[[authorization-consent-schema]]
|
||||
=== Authorization Consent Schema
|
||||
|
||||
The xref:core-model-components.adoc#oauth2-authorization-consent[`OAuth2AuthorizationConsent`] domain object is the simplest to model and contains only a single multi-valued field in addition to a composite key.
|
||||
The following listing shows the `authorizationConsent` schema.
|
||||
|
||||
.Authorization Consent Schema
|
||||
[source,sql]
|
||||
----
|
||||
CREATE TABLE authorizationConsent (
|
||||
registeredClientId varchar(255) NOT NULL,
|
||||
principalName varchar(255) NOT NULL,
|
||||
authorities varchar(1000) NOT NULL,
|
||||
PRIMARY KEY (registeredClientId, principalName)
|
||||
);
|
||||
----
|
||||
|
||||
[[create-jpa-entities]]
|
||||
== Create JPA entities
|
||||
|
||||
The preceding schema examples provide a reference for the structure of the entities we need to create.
|
||||
|
||||
[NOTE]
|
||||
The following entities are minimally annotated and are just examples.
|
||||
They allow the schema to be created dynamically and therefore do not require the above sql scripts to be executed manually.
|
||||
|
||||
* xref:guides/how-to-jpa.adoc#client-entity[Client Entity]
|
||||
* xref:guides/how-to-jpa.adoc#authorization-entity[Authorization Entity]
|
||||
* xref:guides/how-to-jpa.adoc#authorization-consent-entity[Authorization Consent Entity]
|
||||
|
||||
[[client-entity]]
|
||||
=== Client Entity
|
||||
|
||||
The following listing shows the `Client` entity, which is used to persist information mapped from the xref:core-model-components.adoc#registered-client[`RegisteredClient`] domain object.
|
||||
|
||||
[[sample.jpa.entity.client]]
|
||||
.Client Entity
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/jpa/entity/client/Client.java[]
|
||||
----
|
||||
|
||||
[[authorization-entity]]
|
||||
=== Authorization Entity
|
||||
|
||||
The following listing shows the `Authorization` entity, which is used to persist information mapped from the xref:core-model-components.adoc#oauth2-authorization[`OAuth2Authorization`] domain object.
|
||||
|
||||
[[sample.jpa.entity.authorization]]
|
||||
.Authorization Entity
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/jpa/entity/authorization/Authorization.java[]
|
||||
----
|
||||
|
||||
[[authorization-consent-entity]]
|
||||
=== Authorization Consent Entity
|
||||
|
||||
The following listing shows the `AuthorizationConsent` entity, which is used to persist information mapped from the xref:core-model-components.adoc#oauth2-authorization-consent[`OAuth2AuthorizationConsent`] domain object.
|
||||
|
||||
[[sample.jpa.entity.authorizationConsent]]
|
||||
.Authorization Consent Entity
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/jpa/entity/authorizationConsent/AuthorizationConsent.java[]
|
||||
----
|
||||
|
||||
[[create-spring-data-repositories]]
|
||||
== Create Spring Data repositories
|
||||
|
||||
By closely examining the interfaces of each core service and reviewing the `Jdbc` implementations, we can derive a minimal set of queries needed for supporting a JPA version of each interface.
|
||||
|
||||
* xref:guides/how-to-jpa.adoc#client-repository[Client Repository]
|
||||
* xref:guides/how-to-jpa.adoc#authorization-repository[Authorization Repository]
|
||||
* xref:guides/how-to-jpa.adoc#authorization-consent-repository[Authorization Consent Repository]
|
||||
|
||||
[[client-repository]]
|
||||
=== Client Repository
|
||||
|
||||
The following listing shows the `ClientRepository`, which is able to find a xref:guides/how-to-jpa.adoc#client-entity[`Client`] by the `id` and `clientId` fields.
|
||||
|
||||
[[sample.jpa.repository.client]]
|
||||
.Client Repository
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/jpa/repository/client/ClientRepository.java[]
|
||||
----
|
||||
|
||||
[[authorization-repository]]
|
||||
=== Authorization Repository
|
||||
|
||||
The following listing shows the `AuthorizationRepository`, which is able to find an xref:guides/how-to-jpa.adoc#authorization-entity[`Authorization`] by the `id` field as well as the `state`, `authorizationCodeValue`, `accessTokenValue`, `refreshTokenValue`, `userCodeValue` and `deviceCodeValue` token fields.
|
||||
It also allows querying a combination of token fields.
|
||||
|
||||
[[sample.jpa.repository.authorization]]
|
||||
.Authorization Repository
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/jpa/repository/authorization/AuthorizationRepository.java[]
|
||||
----
|
||||
|
||||
[[authorization-consent-repository]]
|
||||
=== Authorization Consent Repository
|
||||
|
||||
The following listing shows the `AuthorizationConsentRepository`, which is able to find and delete an xref:guides/how-to-jpa.adoc#authorization-consent-entity[`AuthorizationConsent`] by the `registeredClientId` and `principalName` fields that form a composite primary key.
|
||||
|
||||
[[sample.jpa.repository.authorizationConsent]]
|
||||
.Authorization Consent Repository
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/jpa/repository/authorizationConsent/AuthorizationConsentRepository.java[]
|
||||
----
|
||||
|
||||
[[implement-core-services]]
|
||||
== Implement core services
|
||||
|
||||
With the above xref:guides/how-to-jpa.adoc#create-jpa-entities[entities] and xref:guides/how-to-jpa.adoc#create-spring-data-repositories[repositories], we can begin implementing the core services.
|
||||
By reviewing the `Jdbc` implementations, we can derive a minimal set of internal utilities for converting to and from string values for enumerations and reading and writing JSON data for attributes, settings, metadata and claims fields.
|
||||
|
||||
[CAUTION]
|
||||
Keep in mind that writing JSON data to text columns with a fixed length has proven problematic with the `Jdbc` implementations.
|
||||
While these examples continue to do so, you may need to split these fields out into a separate table or data store that supports arbitrarily long data values.
|
||||
|
||||
* <<registered-client-repository>>
|
||||
* xref:guides/how-to-jpa.adoc#authorization-service[Authorization Service]
|
||||
* xref:guides/how-to-jpa.adoc#authorization-consent-service[Authorization Consent Service]
|
||||
|
||||
[[registered-client-repository]]
|
||||
=== Registered Client Repository
|
||||
|
||||
The following listing shows the `JpaRegisteredClientRepository`, which uses a xref:guides/how-to-jpa.adoc#client-repository[`ClientRepository`] for persisting a xref:guides/how-to-jpa.adoc#client-entity[`Client`] and maps to and from the xref:core-model-components.adoc#registered-client[`RegisteredClient`] domain object.
|
||||
|
||||
[[sample.jpa.service.client]]
|
||||
.`RegisteredClientRepository` Implementation
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/jpa/service/client/JpaRegisteredClientRepository.java[]
|
||||
----
|
||||
|
||||
[[authorization-service]]
|
||||
=== Authorization Service
|
||||
|
||||
The following listing shows the `JpaOAuth2AuthorizationService`, which uses an xref:guides/how-to-jpa.adoc#authorization-repository[`AuthorizationRepository`] for persisting an xref:guides/how-to-jpa.adoc#authorization-entity[`Authorization`] and maps to and from the xref:core-model-components.adoc#oauth2-authorization[`OAuth2Authorization`] domain object.
|
||||
|
||||
[[sample.jpa.service.authorization]]
|
||||
.`OAuth2AuthorizationService` Implementation
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/jpa/service/authorization/JpaOAuth2AuthorizationService.java[]
|
||||
----
|
||||
|
||||
[[authorization-consent-service]]
|
||||
=== Authorization Consent Service
|
||||
|
||||
The following listing shows the `JpaOAuth2AuthorizationConsentService`, which uses an xref:guides/how-to-jpa.adoc#authorization-consent-repository[`AuthorizationConsentRepository`] for persisting an xref:guides/how-to-jpa.adoc#authorization-consent-entity[`AuthorizationConsent`] and maps to and from the xref:core-model-components.adoc#oauth2-authorization-consent[`OAuth2AuthorizationConsent`] domain object.
|
||||
|
||||
[[sample.jpa.service.authorizationConsent]]
|
||||
.`OAuth2AuthorizationConsentService` Implementation
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/jpa/service/authorizationConsent/JpaOAuth2AuthorizationConsentService.java[]
|
||||
----
|
||||
82
docs/modules/ROOT/pages/guides/how-to-pkce.adoc
Normal file
82
docs/modules/ROOT/pages/guides/how-to-pkce.adoc
Normal file
@@ -0,0 +1,82 @@
|
||||
|
||||
[[how-to-pkce]]
|
||||
= How-to: Authenticate using a Single Page Application with PKCE
|
||||
:index-link: ../how-to.html
|
||||
:docs-dir: ..
|
||||
|
||||
This guide shows how to configure xref:index.adoc[Spring Authorization Server] to support a Single Page Application (SPA) with Proof Key for Code Exchange (PKCE).
|
||||
The purpose of this guide is to demonstrate how to support a public client and require PKCE for client authentication.
|
||||
|
||||
NOTE: Spring Authorization Server will not issue refresh tokens for a public client. We recommend the backend for frontend (BFF) pattern as an alternative to exposing a public client. See https://github.com/spring-projects/spring-authorization-server/issues/297#issue-896744390[gh-297] for more information.
|
||||
|
||||
* xref:guides/how-to-pkce.adoc#enable-cors[Enable CORS]
|
||||
* xref:guides/how-to-pkce.adoc#configure-public-client[Configure a Public Client]
|
||||
* xref:guides/how-to-pkce.adoc#authenticate-with-client[Authenticate with the Client]
|
||||
|
||||
[[enable-cors]]
|
||||
== Enable CORS
|
||||
|
||||
A SPA consists of static resources that can be deployed in a variety of ways.
|
||||
It can be deployed separately from the backend such as with a CDN or separate web server, or it can be deployed along side the backend using Spring Boot.
|
||||
|
||||
When a SPA is hosted under a different domain, Cross Origin Resource Sharing (CORS) can be used to allow the application to communicate with the backend.
|
||||
|
||||
For example, if you have an Angular dev server running locally on port `4200`, you can define a `CorsConfigurationSource` `@Bean` and configure Spring Security to allow pre-flight requests using the `cors()` DSL as in the following example:
|
||||
|
||||
[[enable-cors-configuration]]
|
||||
.Enable CORS
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/pkce/SecurityConfig.java[]
|
||||
----
|
||||
|
||||
TIP: Click on the "Expand folded text" icon in the code sample above to display the full example.
|
||||
|
||||
[[configure-public-client]]
|
||||
== Configure a Public Client
|
||||
|
||||
A SPA cannot securely store credentials and therefore must be treated as a https://datatracker.ietf.org/doc/html/rfc6749#section-2.1[public client^].
|
||||
Public clients should be required to use https://datatracker.ietf.org/doc/html/rfc7636#section-4[Proof Key for Code Exchange] (PKCE).
|
||||
|
||||
Continuing the xref:guides/how-to-pkce.adoc#enable-cors-configuration[earlier] example, you can configure Spring Authorization Server to support a public client using the Client Authentication Method `none` and require PKCE as in the following example:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Yaml::
|
||||
+
|
||||
[[configure-public-client-example]]
|
||||
[source,yaml,role="primary"]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/pkce/application.yml[]
|
||||
----
|
||||
|
||||
Java::
|
||||
+
|
||||
[source,java,role="secondary"]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/pkce/ClientConfig.java[tag=client,indent=0]
|
||||
----
|
||||
======
|
||||
|
||||
NOTE: The `requireProofKey` setting is helpful in situations where you forget to include the `code_challenge` and `code_challenge_method` query parameters because you will receive an error indicating PKCE is required during the xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[Authorization Request] instead of a general client authentication error during the xref:protocol-endpoints.adoc#oauth2-token-endpoint[Token Request].
|
||||
|
||||
[[authenticate-with-client]]
|
||||
== Authenticate with the Client
|
||||
|
||||
Once the server is configured to support a public client, a common question is: _How do I authenticate the client and get an access token?_
|
||||
The short answer is: The same way you would with any other client.
|
||||
|
||||
NOTE: A SPA is a browser-based application and therefore uses the same redirection-based flow as any other client. This question is usually related to an expectation that authentication can be performed via a REST API, which is not the case with OAuth2.
|
||||
|
||||
A more detailed answer requires an understanding of the flow(s) involved in OAuth2 and OpenID Connect, in this case the Authorization Code flow.
|
||||
The steps of the Authorization Code flow are as follows:
|
||||
|
||||
1. The client initiates an OAuth2 request via a redirect to the xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[Authorization Endpoint]. For a public client, this step includes generating the `code_verifier` and calculating the `code_challenge`, which is then sent as a query parameter.
|
||||
2. If the user is not authenticated, the authorization server will redirect to the login page. After authentication, the user is redirected back to the Authorization Endpoint again.
|
||||
3. If the user has not consented to the requested scope(s) and consent is required, the consent page is displayed.
|
||||
4. Once the user has consented, the authorization server generates an `authorization_code` and redirects back to the client via the `redirect_uri`.
|
||||
5. The client obtains the `authorization_code` via a query parameter and performs a request to the xref:protocol-endpoints.adoc#oauth2-token-endpoint[Token Endpoint]. For a public client, this step includes sending the `code_verifier` parameter instead of credentials for authentication.
|
||||
|
||||
As you can see, the flow is fairly involved and this overview only scratches the surface.
|
||||
|
||||
TIP: It is recommended that you use a robust client-side library supported by your single-page app framework to handle the Authorization Code flow.
|
||||
171
docs/modules/ROOT/pages/guides/how-to-social-login.adoc
Normal file
171
docs/modules/ROOT/pages/guides/how-to-social-login.adoc
Normal file
@@ -0,0 +1,171 @@
|
||||
|
||||
[[how-to-social-login]]
|
||||
= How-to: Authenticate using Social Login
|
||||
:index-link: ../how-to.html
|
||||
:docs-dir: ..
|
||||
:github-ref: main
|
||||
:github-base-url: https://github.com/spring-projects/spring-authorization-server/blob/{github-ref}
|
||||
|
||||
This guide shows how to configure xref:index.adoc[Spring Authorization Server] with a social login provider (such as Google, GitHub, etc.) for {spring-security-reference-base-url}/servlet/authentication/index.html[authentication].
|
||||
The purpose of this guide is to demonstrate how to replace {spring-security-reference-base-url}/servlet/authentication/passwords/form.html[Form Login] with {spring-security-reference-base-url}/servlet/oauth2/login/index.html[OAuth 2.0 Login].
|
||||
|
||||
NOTE: Spring Authorization Server is built on {spring-security-reference-base-url}/index.html[Spring Security] and we will be using Spring Security concepts throughout this guide.
|
||||
|
||||
* xref:guides/how-to-social-login.adoc#register-social-login-provider[Register with Social Login Provider]
|
||||
* xref:guides/how-to-social-login.adoc#configure-oauth2-login[Configure OAuth 2.0 Login]
|
||||
* xref:guides/how-to-social-login.adoc#advanced-use-cases[Advanced Use Cases]
|
||||
|
||||
[[register-social-login-provider]]
|
||||
== Register with Social Login Provider
|
||||
|
||||
To get started, you will need to set up an application with your chosen social login provider.
|
||||
Common providers include:
|
||||
|
||||
* https://developers.google.com/identity/openid-connect/openid-connect#appsetup[Google]
|
||||
* https://github.com/settings/developers[GitHub]
|
||||
* https://developers.facebook.com/apps[Facebook]
|
||||
* https://www.okta.com/developer/signup[Okta]
|
||||
|
||||
Follow the steps for your provider until you are asked to specify a Redirect URI.
|
||||
To set up a Redirect URI, choose a `registrationId` (such as `google`, `my-client` or any other unique identifier you wish) which you will use to configure both Spring Security **and** your provider.
|
||||
|
||||
NOTE: The `registrationId` is a unique identifier for the `ClientRegistration` in Spring Security. The default Redirect URI template is `\{baseUrl\}/login/oauth2/code/\{registrationId\}`. See {spring-security-reference-base-url}/servlet/oauth2/login/core.html#oauth2login-sample-redirect-uri[Setting the Redirect URI] in the Spring Security reference for more information.
|
||||
|
||||
TIP: For example, testing locally on port `9000` with a `registrationId` of `google`, your Redirect URI would be `http://localhost:9000/login/oauth2/code/google`. Enter this value as the Redirect URI when setting up the application with your provider.
|
||||
|
||||
Once you've completed the set-up process with your social login provider, you should have obtained credentials (a Client ID and Client Secret).
|
||||
In addition, you will need to reference the provider's documentation and take note of the following values:
|
||||
|
||||
* **Authorization URI**: The endpoint that is used to initiate the `authorization_code` flow at the provider.
|
||||
* **Token URI**: The endpoint that is used to exchange an `authorization_code` for an `access_token` and optionally an `id_token`.
|
||||
* **JWK Set URI**: The endpoint that is used to obtain keys for verifying the signature of a JWT, which is required when an `id_token` is available.
|
||||
* **User Info URI**: The endpoint that is used to obtain user information, which is required when an `id_token` is not available.
|
||||
* **User Name Attribute**: The claim in either the `id_token` or the User Info Response containing the username of the user.
|
||||
|
||||
[[configure-oauth2-login]]
|
||||
== Configure OAuth 2.0 Login
|
||||
|
||||
Once you've xref:guides/how-to-social-login.adoc#register-social-login-provider[registered] with a social login provider, you can proceed to configuring Spring Security for {spring-security-reference-base-url}/servlet/oauth2/login/index.html[OAuth 2.0 Login].
|
||||
|
||||
* xref:guides/how-to-social-login.adoc#configure-oauth2-login-dependency[Add OAuth2 Client Dependency]
|
||||
* xref:guides/how-to-social-login.adoc#configure-oauth2-login-client-registration[Register a Client]
|
||||
* xref:guides/how-to-social-login.adoc#configure-oauth2-login-authentication[Configure Authentication]
|
||||
|
||||
[[configure-oauth2-login-dependency]]
|
||||
=== Add OAuth2 Client Dependency
|
||||
|
||||
First, add the following dependency:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Maven::
|
||||
+
|
||||
[[configure-oauth2-login-maven-dependency]]
|
||||
[source,xml,role="primary",subs="attributes,verbatim"]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-client</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
Gradle::
|
||||
+
|
||||
[[configure-oauth2-login-gradle-dependency]]
|
||||
[source,gradle,role="secondary",subs="attributes,verbatim"]
|
||||
----
|
||||
implementation "org.springframework.boot:spring-boot-starter-oauth2-client"
|
||||
----
|
||||
======
|
||||
|
||||
[[configure-oauth2-login-client-registration]]
|
||||
=== Register a Client
|
||||
|
||||
Next, configure the `ClientRegistration` with the values obtained xref:guides/how-to-social-login.adoc#register-social-login-provider[earlier].
|
||||
Using Okta as an example, configure the following properties:
|
||||
|
||||
[[configure-oauth2-login-okta-example]]
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/sociallogin/application.yml[]
|
||||
----
|
||||
|
||||
NOTE: The `registrationId` in the above example is `my-client`.
|
||||
|
||||
TIP: The above example demonstrates the *recommended* way to set the Provider URL, Client ID and Client Secret using environment variables (`OKTA_BASE_URL`, `OKTA_CLIENT_ID` and `OKTA_CLIENT_SECRET`). See {spring-boot-reference-base-url}/features.html#features.external-config[Externalized Configuration] in the Spring Boot reference for more information.
|
||||
|
||||
This simple example demonstrates a typical configuration, but some providers will require additional configuration.
|
||||
For more information about configuring the `ClientRegistration`, see {spring-security-reference-base-url}/servlet/oauth2/login/core.html#oauth2login-boot-property-mappings[Spring Boot Property Mappings] in the Spring Security reference.
|
||||
|
||||
[[configure-oauth2-login-authentication]]
|
||||
=== Configure Authentication
|
||||
|
||||
Finally, to configure Spring Authorization Server to use a social login provider for authentication, you can use `oauth2Login()` instead of `formLogin()`.
|
||||
You can also automatically redirect an unauthenticated user to the provider by configuring `exceptionHandling()` with an `AuthenticationEntryPoint`.
|
||||
|
||||
Continuing our xref:guides/how-to-social-login.adoc#configure-oauth2-login-okta-example[earlier example], configure Spring Security using a `@Configuration` as in the following example:
|
||||
|
||||
.Configure OAuth 2.0 Login
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/sociallogin/SecurityConfig.java[]
|
||||
----
|
||||
|
||||
<1> A Spring Security filter chain for the xref:{docs-dir}/protocol-endpoints.adoc[Protocol Endpoints].
|
||||
<2> Configure an `AuthenticationEntryPoint` for redirecting to the {spring-security-reference-base-url}/servlet/oauth2/login/advanced.html#oauth2login-advanced-login-page[OAuth 2.0 Login endpoint].
|
||||
<3> A Spring Security filter chain for https://docs.spring.io/spring-security/reference/servlet/authentication/index.html[authentication].
|
||||
<4> Configure {spring-security-reference-base-url}/servlet/oauth2/login/index.html[OAuth 2.0 Login] for authentication.
|
||||
|
||||
If you configured a `UserDetailsService` when xref:getting-started.adoc#developing-your-first-application[getting started], you can remove it now.
|
||||
|
||||
[[advanced-use-cases]]
|
||||
== Advanced Use Cases
|
||||
|
||||
The https://github.com/spring-projects/spring-authorization-server/tree/{github-ref}/samples#demo-sample[demo authorization server sample^] demonstrates advanced configuration options for federating identity providers.
|
||||
Select from the following use cases to see an example of each:
|
||||
|
||||
* I want to xref:guides/how-to-social-login.adoc#advanced-use-cases-capture-users[Capture Users in a Database]
|
||||
* I want to xref:guides/how-to-social-login.adoc#advanced-use-cases-map-claims[Map Claims to an ID Token]
|
||||
|
||||
[[advanced-use-cases-capture-users]]
|
||||
=== Capture Users in a Database
|
||||
|
||||
The following example `AuthenticationSuccessHandler` uses a custom component to capture users in a local database when they first log in:
|
||||
|
||||
.`FederatedIdentityAuthenticationSuccessHandler`
|
||||
[source,java]
|
||||
----
|
||||
include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityAuthenticationSuccessHandler.java[tags=imports;class]
|
||||
----
|
||||
|
||||
Using the `AuthenticationSuccessHandler` above, you can plug in your own `Consumer<OAuth2User>` that can capture users in a database or other data store for concepts like Federated Account Linking or JIT Account Provisioning.
|
||||
Here is an example that simply stores users in-memory:
|
||||
|
||||
.`UserRepositoryOAuth2UserHandler`
|
||||
[source,java]
|
||||
----
|
||||
include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/UserRepositoryOAuth2UserHandler.java[tags=imports;class]
|
||||
----
|
||||
|
||||
[[advanced-use-cases-map-claims]]
|
||||
=== Map Claims to an ID Token
|
||||
|
||||
The following example `OAuth2TokenCustomizer` maps a user's claims from an authentication provider to the `id_token` produced by Spring Authorization Server:
|
||||
|
||||
.`FederatedIdentityIdTokenCustomizer`
|
||||
[source,java]
|
||||
----
|
||||
include::{samples-dir}/demo-authorizationserver/src/main/java/sample/federation/FederatedIdentityIdTokenCustomizer.java[tags=imports;class]
|
||||
----
|
||||
|
||||
You can configure Spring Authorization Server to use this customizer by publishing it as a `@Bean` as in the following example:
|
||||
|
||||
.Configure `FederatedIdentityIdTokenCustomizer`
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public OAuth2TokenCustomizer<JwtEncodingContext> idTokenCustomizer() {
|
||||
return new FederatedIdentityIdTokenCustomizer();
|
||||
}
|
||||
----
|
||||
102
docs/modules/ROOT/pages/guides/how-to-userinfo.adoc
Normal file
102
docs/modules/ROOT/pages/guides/how-to-userinfo.adoc
Normal file
@@ -0,0 +1,102 @@
|
||||
|
||||
[[how-to-userinfo]]
|
||||
= How-to: Customize the OpenID Connect 1.0 UserInfo response
|
||||
:index-link: ../how-to.html
|
||||
:docs-dir: ..
|
||||
|
||||
This guide shows how to customize the xref:protocol-endpoints.adoc#oidc-user-info-endpoint[UserInfo endpoint] of the xref:index.adoc[Spring Authorization Server].
|
||||
The purpose of this guide is to demonstrate how to enable the endpoint and use the available customization options to produce a custom response.
|
||||
|
||||
* xref:guides/how-to-userinfo.adoc#enable-user-info[Enable the User Info Endpoint]
|
||||
* xref:guides/how-to-userinfo.adoc#customize-user-info[Customize the User Info response]
|
||||
|
||||
[[enable-user-info]]
|
||||
== Enable the User Info Endpoint
|
||||
|
||||
The xref:protocol-endpoints.adoc#oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint] is an OAuth2 protected resource, which *REQUIRES* an access token to be sent as a bearer token in the https://openid.net/specs/openid-connect-core-1_0.html#UserInfoRequest[UserInfo request].
|
||||
|
||||
> The Access Token obtained from an OpenID Connect Authentication Request MUST be sent as a Bearer Token, per Section 2 of https://openid.net/specs/openid-connect-core-1_0.html#RFC6750[OAuth 2.0 Bearer Token Usage] [RFC6750].
|
||||
|
||||
Before customizing the response, you need to enable the UserInfo endpoint.
|
||||
The following listing shows how to enable the {spring-security-reference-base-url}/servlet/oauth2/resource-server/jwt.html[OAuth2 resource server configuration].
|
||||
|
||||
[[sample.userinfo]]
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/userinfo/EnableUserInfoSecurityConfig.java[]
|
||||
----
|
||||
|
||||
TIP: Click on the "Expand folded text" icon in the code sample above to display the full example.
|
||||
|
||||
This configuration provides the following:
|
||||
|
||||
<1> A Spring Security filter chain for the xref:{docs-dir}/protocol-endpoints.adoc[Protocol Endpoints].
|
||||
<2> Resource server support that allows User Info requests to be authenticated with access tokens.
|
||||
<3> An instance of `JwtDecoder` used to validate access tokens.
|
||||
|
||||
[[customize-user-info]]
|
||||
== Customize the User Info response
|
||||
|
||||
The following sections describe some options for customizing the user info response.
|
||||
|
||||
* xref:guides/how-to-userinfo.adoc#customize-id-token[Customize the ID Token]
|
||||
* xref:guides/how-to-userinfo.adoc#customize-user-info-mapper[Customize the User Info Mapper]
|
||||
|
||||
[[customize-id-token]]
|
||||
=== Customize the ID Token
|
||||
|
||||
By default, the user info response is generated by using claims from the `id_token` that are returned with the xref:protocol-endpoints.adoc#oauth2-token-endpoint[token response].
|
||||
Using the default strategy, https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims[standard claims] are returned only with the user info response based on the https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims[requested scopes] during authorization.
|
||||
|
||||
The preferred way to customize the user info response is to add standard claims to the `id_token`.
|
||||
The following listing shows how to add claims to the `id_token`.
|
||||
|
||||
[[sample.userinfo.idtoken]]
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/userinfo/idtoken/IdTokenCustomizerConfig.java[]
|
||||
----
|
||||
|
||||
This configuration provides the following:
|
||||
|
||||
<1> An instance of xref:core-model-components.adoc#oauth2-token-customizer[`OAuth2TokenCustomizer`] for customizing the `id_token`.
|
||||
<2> A custom service used to obtain user info in a domain-specific way.
|
||||
|
||||
The following listing shows a custom service for looking up user info in a domain-specific way:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/userinfo/idtoken/OidcUserInfoService.java[]
|
||||
----
|
||||
|
||||
[[customize-user-info-mapper]]
|
||||
=== Customize the User Info Mapper
|
||||
|
||||
To fully customize the user info response, you can provide a custom user info mapper capable of generating the object used to render the response, which is an instance of the `OidcUserInfo` class from Spring Security.
|
||||
The mapper implementation receives an instance of `OidcUserInfoAuthenticationContext` with information about the current request, including the xref:core-model-components.adoc#oauth2-authorization[`OAuth2Authorization`].
|
||||
|
||||
The following listing shows how to use the customization option that is available while working directly with the `OAuth2AuthorizationServerConfigurer`.
|
||||
|
||||
[[sample.userinfo.jwt]]
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/userinfo/jwt/JwtUserInfoMapperSecurityConfig.java[]
|
||||
----
|
||||
|
||||
This configuration maps claims from the access token (which is a JWT when using the xref:getting-started.adoc#sample.gettingStarted[Getting Started config]) to populate the user info response and provides the following:
|
||||
|
||||
<1> A Spring Security filter chain for the xref:{docs-dir}/protocol-endpoints.adoc[Protocol Endpoints].
|
||||
<2> A user info mapper that maps claims in a domain-specific way.
|
||||
<3> An example showing the configuration option for customizing the user info mapper.
|
||||
<4> Resource server support that allows User Info requests to be authenticated with access tokens.
|
||||
<5> An example showing how to apply the `OAuth2AuthorizationServerConfigurer` to the Spring Security configuration.
|
||||
|
||||
The user info mapper is not limited to mapping claims from a JWT, but this is a simple example that demonstrates the customization option.
|
||||
Similar to the xref:guides/how-to-userinfo.adoc#customize-id-token[example shown earlier] where we customize claims of the ID token, you can customize claims of the access token itself ahead of time, as in the following example:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
include::{examples-dir}/main/java/sample/userinfo/jwt/JwtTokenCustomizerConfig.java[]
|
||||
----
|
||||
|
||||
Whether you customize the user info response directly or use this example and customize the access token, you can look up information in a database, perform an LDAP query, make a request to another service, or use any other means of obtaining the information you want to be presented in the user info response.
|
||||
13
docs/modules/ROOT/pages/how-to.adoc
Normal file
13
docs/modules/ROOT/pages/how-to.adoc
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
[[how-to]]
|
||||
= How-to Guides
|
||||
:page-section-summary-toc: 1
|
||||
|
||||
[[how-to-overview]]
|
||||
== List of Guides
|
||||
|
||||
* xref:guides/how-to-pkce.adoc[Authenticate using a Single Page Application with PKCE]
|
||||
* xref:guides/how-to-social-login.adoc[Authenticate using Social Login]
|
||||
* xref:guides/how-to-ext-grant-type.adoc[Implement an Extension Authorization Grant Type]
|
||||
* xref:guides/how-to-userinfo.adoc[Customize the OpenID Connect 1.0 UserInfo response]
|
||||
* xref:guides/how-to-jpa.adoc[Implement core services with JPA]
|
||||
109
docs/modules/ROOT/pages/index.adoc
Normal file
109
docs/modules/ROOT/pages/index.adoc
Normal file
@@ -0,0 +1,109 @@
|
||||
[[top]]
|
||||
= Overview
|
||||
:page-section-summary-toc: 1
|
||||
Joe Grandja, Steve Riesenberg
|
||||
v{spring-authorization-server-version}
|
||||
:docinfo: private-footer
|
||||
:nofooter:
|
||||
|
||||
This site contains reference documentation and how-to guides for Spring Authorization Server.
|
||||
|
||||
[horizontal]
|
||||
xref:index.adoc#introducing-spring-authorization-server[Introduction] :: Introduction and feature list
|
||||
xref:getting-help.adoc[Getting Help] :: Links to samples, questions and issues
|
||||
xref:getting-started.adoc[Getting Started] :: System requirements, dependencies and developing your first application
|
||||
xref:configuration-model.adoc[Configuration Model] :: Default configuration and customizing the configuration
|
||||
xref:core-model-components.adoc[Core Model / Components] :: Core domain model and component interfaces
|
||||
xref:protocol-endpoints.adoc[Protocol Endpoints] :: OAuth2 and OpenID Connect 1.0 protocol endpoint implementations
|
||||
xref:how-to.adoc[How-to Guides] :: Guides to get the most from Spring Authorization Server
|
||||
|
||||
|
||||
[[introducing-spring-authorization-server]]
|
||||
== Introducing Spring Authorization Server
|
||||
|
||||
Spring Authorization Server is a framework that provides implementations of the https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07[OAuth 2.1] and https://openid.net/specs/openid-connect-core-1_0.html[OpenID Connect 1.0] specifications and other related specifications.
|
||||
It is built on top of https://spring.io/projects/spring-security[Spring Security] to provide a secure, light-weight, and customizable foundation for building OpenID Connect 1.0 Identity Providers and OAuth2 Authorization Server products.
|
||||
|
||||
[[feature-list]]
|
||||
== Feature List
|
||||
|
||||
Spring Authorization Server supports the following features:
|
||||
|
||||
[cols="2a,4a,6a"]
|
||||
|===
|
||||
|Category |Feature |Related specifications
|
||||
|
||||
|xref:protocol-endpoints.adoc#oauth2-token-endpoint[Authorization Grant]
|
||||
|
|
||||
* Authorization Code
|
||||
** xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[User Consent]
|
||||
* Client Credentials
|
||||
* Refresh Token
|
||||
* Device Code
|
||||
** xref:protocol-endpoints.adoc#oauth2-device-verification-endpoint[User Consent]
|
||||
|
|
||||
* The OAuth 2.1 Authorization Framework (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07[draft])
|
||||
** https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-4.1[Authorization Code Grant]
|
||||
** https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-4.2[Client Credentials Grant]
|
||||
** https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-4.3[Refresh Token Grant]
|
||||
* OpenID Connect Core 1.0 (https://openid.net/specs/openid-connect-core-1_0.html[spec])
|
||||
** https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth[Authorization Code Flow]
|
||||
* OAuth 2.0 Device Authorization Grant
|
||||
(https://tools.ietf.org/html/rfc8628[spec])
|
||||
** https://tools.ietf.org/html/rfc8628#section-3[Device Flow]
|
||||
|
||||
|xref:core-model-components.adoc#oauth2-token-generator[Token Formats]
|
||||
|
|
||||
* Self-contained (JWT)
|
||||
* Reference (Opaque)
|
||||
|
|
||||
* JSON Web Token (JWT) (https://tools.ietf.org/html/rfc7519[RFC 7519])
|
||||
* JSON Web Signature (JWS) (https://tools.ietf.org/html/rfc7515[RFC 7515])
|
||||
|
||||
|xref:configuration-model.adoc#configuring-client-authentication[Client Authentication]
|
||||
|
|
||||
* `client_secret_basic`
|
||||
* `client_secret_post`
|
||||
* `client_secret_jwt`
|
||||
* `private_key_jwt`
|
||||
* `none` (public clients)
|
||||
|
|
||||
* The OAuth 2.1 Authorization Framework (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-2.4[Client Authentication])
|
||||
* JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication (https://tools.ietf.org/html/rfc7523[RFC 7523])
|
||||
* Proof Key for Code Exchange by OAuth Public Clients (PKCE) (https://tools.ietf.org/html/rfc7636[RFC 7636])
|
||||
|
||||
|xref:protocol-endpoints.adoc[Protocol Endpoints]
|
||||
|
|
||||
* xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[OAuth2 Authorization Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-device-authorization-endpoint[OAuth2 Device Authorization Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-device-verification-endpoint[OAuth2 Device Verification Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-token-endpoint[OAuth2 Token Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-token-introspection-endpoint[OAuth2 Token Introspection Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-token-revocation-endpoint[OAuth2 Token Revocation Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oauth2-authorization-server-metadata-endpoint[OAuth2 Authorization Server Metadata Endpoint]
|
||||
* xref:protocol-endpoints.adoc#jwk-set-endpoint[JWK Set Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oidc-provider-configuration-endpoint[OpenID Connect 1.0 Provider Configuration Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oidc-logout-endpoint[OpenID Connect 1.0 Logout Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo Endpoint]
|
||||
* xref:protocol-endpoints.adoc#oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration Endpoint]
|
||||
|
|
||||
* The OAuth 2.1 Authorization Framework (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07[draft])
|
||||
** https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-3.1[Authorization Endpoint]
|
||||
** https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-07#section-3.2[Token Endpoint]
|
||||
* OAuth 2.0 Device Authorization Grant (https://tools.ietf.org/html/rfc8628[RFC 8628])
|
||||
** https://tools.ietf.org/html/rfc8628#section-3.1[Device Authorization Endpoint]
|
||||
** https://tools.ietf.org/html/rfc8628#section-3.3[Device Verification Endpoint]
|
||||
* OAuth 2.0 Token Introspection (https://tools.ietf.org/html/rfc7662[RFC 7662])
|
||||
* OAuth 2.0 Token Revocation (https://tools.ietf.org/html/rfc7009[RFC 7009])
|
||||
* OAuth 2.0 Authorization Server Metadata (https://tools.ietf.org/html/rfc8414[RFC 8414])
|
||||
* JSON Web Key (JWK) (https://tools.ietf.org/html/rfc7517[RFC 7517])
|
||||
* OpenID Connect Discovery 1.0 (https://openid.net/specs/openid-connect-discovery-1_0.html[spec])
|
||||
** https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[Provider Configuration Endpoint]
|
||||
* OpenID Connect RP-Initiated Logout 1.0 (https://openid.net/specs/openid-connect-rpinitiated-1_0.html[spec])
|
||||
** https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout[Logout Endpoint]
|
||||
* OpenID Connect Core 1.0 (https://openid.net/specs/openid-connect-core-1_0.html[spec])
|
||||
** https://openid.net/specs/openid-connect-core-1_0.html#UserInfo[UserInfo Endpoint]
|
||||
* OpenID Connect Dynamic Client Registration 1.0 (https://openid.net/specs/openid-connect-registration-1_0.html[spec])
|
||||
** https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration[Client Registration Endpoint]
|
||||
** https://openid.net/specs/openid-connect-registration-1_0.html#ClientConfigurationEndpoint[Client Configuration Endpoint]
|
||||
|===
|
||||
665
docs/modules/ROOT/pages/protocol-endpoints.adoc
Normal file
665
docs/modules/ROOT/pages/protocol-endpoints.adoc
Normal file
@@ -0,0 +1,665 @@
|
||||
[[protocol-endpoints]]
|
||||
= Protocol Endpoints
|
||||
|
||||
[[oauth2-authorization-endpoint]]
|
||||
== OAuth2 Authorization Endpoint
|
||||
|
||||
`OAuth2AuthorizationEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc6749#section-3.1[OAuth2 Authorization endpoint].
|
||||
It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1[OAuth2 authorization requests].
|
||||
|
||||
`OAuth2AuthorizationEndpointConfigurer` provides the following configuration options:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.authorizationEndpoint(authorizationEndpoint ->
|
||||
authorizationEndpoint
|
||||
.authorizationRequestConverter(authorizationRequestConverter) <1>
|
||||
.authorizationRequestConverters(authorizationRequestConvertersConsumer) <2>
|
||||
.authenticationProvider(authenticationProvider) <3>
|
||||
.authenticationProviders(authenticationProvidersConsumer) <4>
|
||||
.authorizationResponseHandler(authorizationResponseHandler) <5>
|
||||
.errorResponseHandler(errorResponseHandler) <6>
|
||||
.consentPage("/oauth2/v1/authorize") <7>
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `authorizationRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract an https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1[OAuth2 authorization request] (or consent) from `HttpServletRequest` to an instance of `OAuth2AuthorizationCodeRequestAuthenticationToken` or `OAuth2AuthorizationConsentAuthenticationToken`.
|
||||
<2> `authorizationRequestConverters()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationConverter``'s allowing the ability to add, remove, or customize a specific `AuthenticationConverter`.
|
||||
<3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2AuthorizationCodeRequestAuthenticationToken` or `OAuth2AuthorizationConsentAuthenticationToken`.
|
||||
<4> `authenticationProviders()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationProvider``'s allowing the ability to add, remove, or customize a specific `AuthenticationProvider`.
|
||||
<5> `authorizationResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OAuth2AuthorizationCodeRequestAuthenticationToken` and returning the https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2[OAuth2AuthorizationResponse].
|
||||
<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthorizationCodeRequestAuthenticationException` and returning the https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1[OAuth2Error response].
|
||||
<7> `consentPage()`: The `URI` of the custom consent page to redirect resource owners to if consent is required during the authorization request flow.
|
||||
|
||||
`OAuth2AuthorizationEndpointConfigurer` configures the `OAuth2AuthorizationEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`OAuth2AuthorizationEndpointFilter` is the `Filter` that processes OAuth2 authorization requests (and consents).
|
||||
|
||||
`OAuth2AuthorizationEndpointFilter` is configured with the following defaults:
|
||||
|
||||
* `*AuthenticationConverter*` -- A `DelegatingAuthenticationConverter` composed of `OAuth2AuthorizationCodeRequestAuthenticationConverter` and `OAuth2AuthorizationConsentAuthenticationConverter`.
|
||||
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2AuthorizationCodeRequestAuthenticationProvider` and `OAuth2AuthorizationConsentAuthenticationProvider`.
|
||||
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OAuth2AuthorizationCodeRequestAuthenticationToken` and returns the `OAuth2AuthorizationResponse`.
|
||||
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthorizationCodeRequestAuthenticationException` and returns the `OAuth2Error` response.
|
||||
|
||||
[[oauth2-authorization-endpoint-customizing-authorization-request-validation]]
|
||||
=== Customizing Authorization Request Validation
|
||||
|
||||
`OAuth2AuthorizationCodeRequestAuthenticationValidator` is the default validator used for validating specific OAuth2 authorization request parameters used in the Authorization Code Grant.
|
||||
The default implementation validates the `redirect_uri` and `scope` parameters.
|
||||
If validation fails, an `OAuth2AuthorizationCodeRequestAuthenticationException` is thrown.
|
||||
|
||||
`OAuth2AuthorizationCodeRequestAuthenticationProvider` provides the ability to override the default authorization request validation by supplying a custom authentication validator of type `Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext>` to `setAuthenticationValidator()`.
|
||||
|
||||
[TIP]
|
||||
`OAuth2AuthorizationCodeRequestAuthenticationContext` holds the `OAuth2AuthorizationCodeRequestAuthenticationToken`, which contains the OAuth2 authorization request parameters.
|
||||
|
||||
[IMPORTANT]
|
||||
If validation fails, the authentication validator *MUST* throw `OAuth2AuthorizationCodeRequestAuthenticationException`.
|
||||
|
||||
A common use case during the development life cycle phase is to allow for `localhost` in the `redirect_uri` parameter.
|
||||
|
||||
The following example shows how to configure `OAuth2AuthorizationCodeRequestAuthenticationProvider` with a custom authentication validator that allows for `localhost` in the `redirect_uri` parameter:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.authorizationEndpoint(authorizationEndpoint ->
|
||||
authorizationEndpoint
|
||||
.authenticationProviders(configureAuthenticationValidator())
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
|
||||
return (authenticationProviders) ->
|
||||
authenticationProviders.forEach((authenticationProvider) -> {
|
||||
if (authenticationProvider instanceof OAuth2AuthorizationCodeRequestAuthenticationProvider) {
|
||||
Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> authenticationValidator =
|
||||
// Override default redirect_uri validator
|
||||
new CustomRedirectUriValidator()
|
||||
// Reuse default scope validator
|
||||
.andThen(OAuth2AuthorizationCodeRequestAuthenticationValidator.DEFAULT_SCOPE_VALIDATOR);
|
||||
|
||||
((OAuth2AuthorizationCodeRequestAuthenticationProvider) authenticationProvider)
|
||||
.setAuthenticationValidator(authenticationValidator);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static class CustomRedirectUriValidator implements Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> {
|
||||
|
||||
@Override
|
||||
public void accept(OAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext) {
|
||||
OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication =
|
||||
authenticationContext.getAuthentication();
|
||||
RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
|
||||
String requestedRedirectUri = authorizationCodeRequestAuthentication.getRedirectUri();
|
||||
|
||||
// Use exact string matching when comparing client redirect URIs against pre-registered URIs
|
||||
if (!registeredClient.getRedirectUris().contains(requestedRedirectUri)) {
|
||||
OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST);
|
||||
throw new OAuth2AuthorizationCodeRequestAuthenticationException(error, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
[[oauth2-device-authorization-endpoint]]
|
||||
== OAuth2 Device Authorization Endpoint
|
||||
|
||||
`OAuth2DeviceAuthorizationEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc8628#section-3.1[OAuth2 Device Authorization endpoint].
|
||||
It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for OAuth2 device authorization requests.
|
||||
|
||||
`OAuth2DeviceAuthorizationEndpointConfigurer` provides the following configuration options:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
|
||||
deviceAuthorizationEndpoint
|
||||
.deviceAuthorizationRequestConverter(deviceAuthorizationRequestConverter) <1>
|
||||
.deviceAuthorizationRequestConverters(deviceAuthorizationRequestConvertersConsumer) <2>
|
||||
.authenticationProvider(authenticationProvider) <3>
|
||||
.authenticationProviders(authenticationProvidersConsumer) <4>
|
||||
.deviceAuthorizationResponseHandler(deviceAuthorizationResponseHandler) <5>
|
||||
.errorResponseHandler(errorResponseHandler) <6>
|
||||
.verificationUri("/oauth2/v1/device_verification") <7>
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `deviceAuthorizationRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract an https://datatracker.ietf.org/doc/html/rfc8628#section-3.1[OAuth2 device authorization request] from `HttpServletRequest` to an instance of `OAuth2DeviceAuthorizationRequestAuthenticationToken`.
|
||||
<2> `deviceAuthorizationRequestConverters()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationConverter``'s allowing the ability to add, remove, or customize a specific `AuthenticationConverter`.
|
||||
<3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2DeviceAuthorizationRequestAuthenticationToken`.
|
||||
<4> `authenticationProviders()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationProvider``'s allowing the ability to add, remove, or customize a specific `AuthenticationProvider`.
|
||||
<5> `deviceAuthorizationResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OAuth2DeviceAuthorizationRequestAuthenticationToken` and returning the https://datatracker.ietf.org/doc/html/rfc8628#section-3.2[OAuth2DeviceAuthorizationResponse].
|
||||
<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the https://datatracker.ietf.org/doc/html/rfc6749#section-5.2[OAuth2Error response].
|
||||
<7> `verificationUri()`: The `URI` of the custom end-user verification page to direct resource owners to on a secondary device.
|
||||
|
||||
`OAuth2DeviceAuthorizationEndpointConfigurer` configures the `OAuth2DeviceAuthorizationEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`OAuth2DeviceAuthorizationEndpointFilter` is the `Filter` that processes OAuth2 device authorization requests.
|
||||
|
||||
`OAuth2DeviceAuthorizationEndpointFilter` is configured with the following defaults:
|
||||
|
||||
* `*AuthenticationConverter*` -- An `OAuth2DeviceAuthorizationRequestAuthenticationConverter`.
|
||||
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2DeviceAuthorizationRequestAuthenticationProvider`.
|
||||
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OAuth2DeviceAuthorizationRequestAuthenticationToken` and returns the `OAuth2DeviceAuthorizationResponse`.
|
||||
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
|
||||
|
||||
[[oauth2-device-verification-endpoint]]
|
||||
== OAuth2 Device Verification Endpoint
|
||||
|
||||
`OAuth2DeviceVerificationEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc8628#section-3.3[OAuth2 Device Verification endpoint] (or "User Interaction").
|
||||
It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for OAuth2 device verification requests.
|
||||
|
||||
`OAuth2DeviceVerificationEndpointConfigurer` provides the following configuration options:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.deviceVerificationEndpoint(deviceVerificationEndpoint ->
|
||||
deviceVerificationEndpoint
|
||||
.deviceVerificationRequestConverter(deviceVerificationRequestConverter) <1>
|
||||
.deviceVerificationRequestConverters(deviceVerificationRequestConvertersConsumer) <2>
|
||||
.authenticationProvider(authenticationProvider) <3>
|
||||
.authenticationProviders(authenticationProvidersConsumer) <4>
|
||||
.deviceVerificationResponseHandler(deviceVerificationResponseHandler) <5>
|
||||
.errorResponseHandler(errorResponseHandler) <6>
|
||||
.consentPage("/oauth2/v1/consent") <7>
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `deviceVerificationRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract an https://datatracker.ietf.org/doc/html/rfc8628#section-3.3[OAuth2 device verification request] (or consent) from `HttpServletRequest` to an instance of `OAuth2DeviceVerificationAuthenticationToken` or `OAuth2DeviceAuthorizationConsentAuthenticationToken`.
|
||||
<2> `deviceVerificationRequestConverters()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationConverter``'s allowing the ability to add, remove, or customize a specific `AuthenticationConverter`.
|
||||
<3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2DeviceVerificationAuthenticationToken` or `OAuth2DeviceAuthorizationConsentAuthenticationToken`.
|
||||
<4> `authenticationProviders()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationProvider``'s allowing the ability to add, remove, or customize a specific `AuthenticationProvider`.
|
||||
<5> `deviceVerificationResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OAuth2DeviceVerificationAuthenticationToken` and directing the resource owner to return to their device.
|
||||
<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the error response.
|
||||
<7> `consentPage()`: The `URI` of the custom consent page to redirect resource owners to if consent is required during the device verification request flow.
|
||||
|
||||
`OAuth2DeviceVerificationEndpointConfigurer` configures the `OAuth2DeviceVerificationEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`OAuth2DeviceVerificationEndpointFilter` is the `Filter` that processes OAuth2 device verification requests (and consents).
|
||||
|
||||
`OAuth2DeviceVerificationEndpointFilter` is configured with the following defaults:
|
||||
|
||||
* `*AuthenticationConverter*` -- A `DelegatingAuthenticationConverter` composed of `OAuth2DeviceVerificationAuthenticationConverter` and `OAuth2DeviceAuthorizationConsentAuthenticationConverter`.
|
||||
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2DeviceVerificationAuthenticationProvider` and `OAuth2DeviceAuthorizationConsentAuthenticationProvider`.
|
||||
* `*AuthenticationSuccessHandler*` -- A `SimpleUrlAuthenticationSuccessHandler` that handles an "`authenticated`" `OAuth2DeviceVerificationAuthenticationToken` and redirects the user to a success page (`/?success`).
|
||||
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
|
||||
|
||||
[[oauth2-token-endpoint]]
|
||||
== OAuth2 Token Endpoint
|
||||
|
||||
`OAuth2TokenEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc6749#section-3.2[OAuth2 Token endpoint].
|
||||
It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3[OAuth2 access token requests].
|
||||
|
||||
`OAuth2TokenEndpointConfigurer` provides the following configuration options:
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.tokenEndpoint(tokenEndpoint ->
|
||||
tokenEndpoint
|
||||
.accessTokenRequestConverter(accessTokenRequestConverter) <1>
|
||||
.accessTokenRequestConverters(accessTokenRequestConvertersConsumer) <2>
|
||||
.authenticationProvider(authenticationProvider) <3>
|
||||
.authenticationProviders(authenticationProvidersConsumer) <4>
|
||||
.accessTokenResponseHandler(accessTokenResponseHandler) <5>
|
||||
.errorResponseHandler(errorResponseHandler) <6>
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `accessTokenRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract an https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3[OAuth2 access token request] from `HttpServletRequest` to an instance of `OAuth2AuthorizationGrantAuthenticationToken`.
|
||||
<2> `accessTokenRequestConverters()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationConverter``'s allowing the ability to add, remove, or customize a specific `AuthenticationConverter`.
|
||||
<3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2AuthorizationGrantAuthenticationToken`.
|
||||
<4> `authenticationProviders()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationProvider``'s allowing the ability to add, remove, or customize a specific `AuthenticationProvider`.
|
||||
<5> `accessTokenResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an `OAuth2AccessTokenAuthenticationToken` and returning the https://datatracker.ietf.org/doc/html/rfc6749#section-5.1[`OAuth2AccessTokenResponse`].
|
||||
<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the https://datatracker.ietf.org/doc/html/rfc6749#section-5.2[OAuth2Error response].
|
||||
|
||||
`OAuth2TokenEndpointConfigurer` configures the `OAuth2TokenEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`OAuth2TokenEndpointFilter` is the `Filter` that processes OAuth2 access token requests.
|
||||
|
||||
The supported https://datatracker.ietf.org/doc/html/rfc6749#section-1.3[authorization grant types] are `authorization_code`, `refresh_token`, `client_credentials`, and `urn:ietf:params:oauth:grant-type:device_code`.
|
||||
|
||||
`OAuth2TokenEndpointFilter` is configured with the following defaults:
|
||||
|
||||
* `*AuthenticationConverter*` -- A `DelegatingAuthenticationConverter` composed of `OAuth2AuthorizationCodeAuthenticationConverter`, `OAuth2RefreshTokenAuthenticationConverter`, `OAuth2ClientCredentialsAuthenticationConverter`, and `OAuth2DeviceCodeAuthenticationConverter`.
|
||||
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2AuthorizationCodeAuthenticationProvider`, `OAuth2RefreshTokenAuthenticationProvider`, `OAuth2ClientCredentialsAuthenticationProvider`, and `OAuth2DeviceCodeAuthenticationProvider`.
|
||||
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an `OAuth2AccessTokenAuthenticationToken` and returns the `OAuth2AccessTokenResponse`.
|
||||
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
|
||||
|
||||
[[oauth2-token-introspection-endpoint]]
|
||||
== OAuth2 Token Introspection Endpoint
|
||||
|
||||
`OAuth2TokenIntrospectionEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc7662#section-2[OAuth2 Token Introspection endpoint].
|
||||
It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for https://datatracker.ietf.org/doc/html/rfc7662#section-2.1[OAuth2 introspection requests].
|
||||
|
||||
`OAuth2TokenIntrospectionEndpointConfigurer` provides the following configuration options:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint ->
|
||||
tokenIntrospectionEndpoint
|
||||
.introspectionRequestConverter(introspectionRequestConverter) <1>
|
||||
.introspectionRequestConverters(introspectionRequestConvertersConsumer) <2>
|
||||
.authenticationProvider(authenticationProvider) <3>
|
||||
.authenticationProviders(authenticationProvidersConsumer) <4>
|
||||
.introspectionResponseHandler(introspectionResponseHandler) <5>
|
||||
.errorResponseHandler(errorResponseHandler) <6>
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `introspectionRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract an https://datatracker.ietf.org/doc/html/rfc7662#section-2.1[OAuth2 introspection request] from `HttpServletRequest` to an instance of `OAuth2TokenIntrospectionAuthenticationToken`.
|
||||
<2> `introspectionRequestConverters()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationConverter``'s allowing the ability to add, remove, or customize a specific `AuthenticationConverter`.
|
||||
<3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2TokenIntrospectionAuthenticationToken`.
|
||||
<4> `authenticationProviders()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationProvider``'s allowing the ability to add, remove, or customize a specific `AuthenticationProvider`.
|
||||
<5> `introspectionResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OAuth2TokenIntrospectionAuthenticationToken` and returning the https://datatracker.ietf.org/doc/html/rfc7662#section-2.2[OAuth2TokenIntrospection response].
|
||||
<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the https://datatracker.ietf.org/doc/html/rfc7662#section-2.3[OAuth2Error response].
|
||||
|
||||
`OAuth2TokenIntrospectionEndpointConfigurer` configures the `OAuth2TokenIntrospectionEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`OAuth2TokenIntrospectionEndpointFilter` is the `Filter` that processes OAuth2 introspection requests.
|
||||
|
||||
`OAuth2TokenIntrospectionEndpointFilter` is configured with the following defaults:
|
||||
|
||||
* `*AuthenticationConverter*` -- An `OAuth2TokenIntrospectionAuthenticationConverter`.
|
||||
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2TokenIntrospectionAuthenticationProvider`.
|
||||
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OAuth2TokenIntrospectionAuthenticationToken` and returns the `OAuth2TokenIntrospection` response.
|
||||
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
|
||||
|
||||
[[oauth2-token-revocation-endpoint]]
|
||||
== OAuth2 Token Revocation Endpoint
|
||||
|
||||
`OAuth2TokenRevocationEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc7009#section-2[OAuth2 Token Revocation endpoint].
|
||||
It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for https://datatracker.ietf.org/doc/html/rfc7009#section-2.1[OAuth2 revocation requests].
|
||||
|
||||
`OAuth2TokenRevocationEndpointConfigurer` provides the following configuration options:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.tokenRevocationEndpoint(tokenRevocationEndpoint ->
|
||||
tokenRevocationEndpoint
|
||||
.revocationRequestConverter(revocationRequestConverter) <1>
|
||||
.revocationRequestConverters(revocationRequestConvertersConsumer) <2>
|
||||
.authenticationProvider(authenticationProvider) <3>
|
||||
.authenticationProviders(authenticationProvidersConsumer) <4>
|
||||
.revocationResponseHandler(revocationResponseHandler) <5>
|
||||
.errorResponseHandler(errorResponseHandler) <6>
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `revocationRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract an https://datatracker.ietf.org/doc/html/rfc7009#section-2.1[OAuth2 revocation request] from `HttpServletRequest` to an instance of `OAuth2TokenRevocationAuthenticationToken`.
|
||||
<2> `revocationRequestConverters()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationConverter``'s allowing the ability to add, remove, or customize a specific `AuthenticationConverter`.
|
||||
<3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2TokenRevocationAuthenticationToken`.
|
||||
<4> `authenticationProviders()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationProvider``'s allowing the ability to add, remove, or customize a specific `AuthenticationProvider`.
|
||||
<5> `revocationResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OAuth2TokenRevocationAuthenticationToken` and returning the https://datatracker.ietf.org/doc/html/rfc7009#section-2.2[OAuth2 revocation response].
|
||||
<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the https://datatracker.ietf.org/doc/html/rfc7009#section-2.2.1[OAuth2Error response].
|
||||
|
||||
`OAuth2TokenRevocationEndpointConfigurer` configures the `OAuth2TokenRevocationEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`OAuth2TokenRevocationEndpointFilter` is the `Filter` that processes OAuth2 revocation requests.
|
||||
|
||||
`OAuth2TokenRevocationEndpointFilter` is configured with the following defaults:
|
||||
|
||||
* `*AuthenticationConverter*` -- An `OAuth2TokenRevocationAuthenticationConverter`.
|
||||
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2TokenRevocationAuthenticationProvider`.
|
||||
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OAuth2TokenRevocationAuthenticationToken` and returns the OAuth2 revocation response.
|
||||
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
|
||||
|
||||
[[oauth2-authorization-server-metadata-endpoint]]
|
||||
== OAuth2 Authorization Server Metadata Endpoint
|
||||
|
||||
`OAuth2AuthorizationServerMetadataEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc8414#section-3[OAuth2 Authorization Server Metadata endpoint].
|
||||
It defines an extension point that lets you customize the https://datatracker.ietf.org/doc/html/rfc8414#section-3.2[OAuth2 Authorization Server Metadata response].
|
||||
|
||||
`OAuth2AuthorizationServerMetadataEndpointConfigurer` provides the following configuration option:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint ->
|
||||
authorizationServerMetadataEndpoint
|
||||
.authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer)); <1>
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `authorizationServerMetadataCustomizer()`: The `Consumer` providing access to the `OAuth2AuthorizationServerMetadata.Builder` allowing the ability to customize the claims of the Authorization Server's configuration.
|
||||
|
||||
`OAuth2AuthorizationServerMetadataEndpointConfigurer` configures the `OAuth2AuthorizationServerMetadataEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`OAuth2AuthorizationServerMetadataEndpointFilter` is the `Filter` that returns the https://datatracker.ietf.org/doc/html/rfc8414#section-3.2[OAuth2AuthorizationServerMetadata response].
|
||||
|
||||
[[jwk-set-endpoint]]
|
||||
== JWK Set Endpoint
|
||||
|
||||
`OAuth2AuthorizationServerConfigurer` provides support for the https://datatracker.ietf.org/doc/html/rfc7517[JWK Set endpoint].
|
||||
|
||||
`OAuth2AuthorizationServerConfigurer` configures the `NimbusJwkSetEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`NimbusJwkSetEndpointFilter` is the `Filter` that returns the https://datatracker.ietf.org/doc/html/rfc7517#section-5[JWK Set].
|
||||
|
||||
[NOTE]
|
||||
The JWK Set endpoint is configured *only* if a `JWKSource<SecurityContext>` `@Bean` is registered.
|
||||
|
||||
[[oidc-provider-configuration-endpoint]]
|
||||
== OpenID Connect 1.0 Provider Configuration Endpoint
|
||||
|
||||
`OidcProviderConfigurationEndpointConfigurer` provides the ability to customize the https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig[OpenID Connect 1.0 Provider Configuration endpoint].
|
||||
It defines an extension point that lets you customize the https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse[OpenID Provider Configuration response].
|
||||
|
||||
`OidcProviderConfigurationEndpointConfigurer` provides the following configuration option:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.oidc(oidc ->
|
||||
oidc
|
||||
.providerConfigurationEndpoint(providerConfigurationEndpoint ->
|
||||
providerConfigurationEndpoint
|
||||
.providerConfigurationCustomizer(providerConfigurationCustomizer) <1>
|
||||
)
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `providerConfigurationCustomizer()`: The `Consumer` providing access to the `OidcProviderConfiguration.Builder` allowing the ability to customize the claims of the OpenID Provider's configuration.
|
||||
|
||||
`OidcProviderConfigurationEndpointConfigurer` configures the `OidcProviderConfigurationEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`OidcProviderConfigurationEndpointFilter` is the `Filter` that returns the https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse[OidcProviderConfiguration response].
|
||||
|
||||
[[oidc-logout-endpoint]]
|
||||
== OpenID Connect 1.0 Logout Endpoint
|
||||
|
||||
`OidcLogoutEndpointConfigurer` provides the ability to customize the https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout[OpenID Connect 1.0 Logout endpoint].
|
||||
It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for RP-Initiated Logout requests.
|
||||
|
||||
`OidcLogoutEndpointConfigurer` provides the following configuration options:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.oidc(oidc ->
|
||||
oidc
|
||||
.logoutEndpoint(logoutEndpoint ->
|
||||
logoutEndpoint
|
||||
.logoutRequestConverter(logoutRequestConverter) <1>
|
||||
.logoutRequestConverters(logoutRequestConvertersConsumer) <2>
|
||||
.authenticationProvider(authenticationProvider) <3>
|
||||
.authenticationProviders(authenticationProvidersConsumer) <4>
|
||||
.logoutResponseHandler(logoutResponseHandler) <5>
|
||||
.errorResponseHandler(errorResponseHandler) <6>
|
||||
)
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `logoutRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract a https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout[Logout request] from `HttpServletRequest` to an instance of `OidcLogoutAuthenticationToken`.
|
||||
<2> `logoutRequestConverters()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationConverter``'s allowing the ability to add, remove, or customize a specific `AuthenticationConverter`.
|
||||
<3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OidcLogoutAuthenticationToken`.
|
||||
<4> `authenticationProviders()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationProvider``'s allowing the ability to add, remove, or customize a specific `AuthenticationProvider`.
|
||||
<5> `logoutResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OidcLogoutAuthenticationToken` and performing the logout.
|
||||
<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the error response.
|
||||
|
||||
`OidcLogoutEndpointConfigurer` configures the `OidcLogoutEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`OidcLogoutEndpointFilter` is the `Filter` that processes https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout[RP-Initiated Logout requests] and performs the logout of the End-User.
|
||||
|
||||
`OidcLogoutEndpointFilter` is configured with the following defaults:
|
||||
|
||||
* `*AuthenticationConverter*` -- An `OidcLogoutAuthenticationConverter`.
|
||||
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OidcLogoutAuthenticationProvider`.
|
||||
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OidcLogoutAuthenticationToken` and performs the logout.
|
||||
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
|
||||
|
||||
[NOTE]
|
||||
`OidcLogoutAuthenticationProvider` uses a xref:core-model-components.adoc#session-registry[`SessionRegistry`] to look up the `SessionInformation` instance associated to the End-User requesting to be logged out.
|
||||
|
||||
[TIP]
|
||||
`OidcClientInitiatedLogoutSuccessHandler` is the corresponding configuration in Spring Security’s OAuth2 Client support for configuring {spring-security-reference-base-url}/servlet/oauth2/login/advanced.html#oauth2login-advanced-oidc-logout[OpenID Connect 1.0 RP-Initiated Logout].
|
||||
|
||||
[[oidc-user-info-endpoint]]
|
||||
== OpenID Connect 1.0 UserInfo Endpoint
|
||||
|
||||
`OidcUserInfoEndpointConfigurer` provides the ability to customize the https://openid.net/specs/openid-connect-core-1_0.html#UserInfo[OpenID Connect 1.0 UserInfo endpoint].
|
||||
It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for https://openid.net/specs/openid-connect-core-1_0.html#UserInfoRequest[UserInfo requests].
|
||||
|
||||
`OidcUserInfoEndpointConfigurer` provides the following configuration options:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.oidc(oidc ->
|
||||
oidc
|
||||
.userInfoEndpoint(userInfoEndpoint ->
|
||||
userInfoEndpoint
|
||||
.userInfoRequestConverter(userInfoRequestConverter) <1>
|
||||
.userInfoRequestConverters(userInfoRequestConvertersConsumer) <2>
|
||||
.authenticationProvider(authenticationProvider) <3>
|
||||
.authenticationProviders(authenticationProvidersConsumer) <4>
|
||||
.userInfoResponseHandler(userInfoResponseHandler) <5>
|
||||
.errorResponseHandler(errorResponseHandler) <6>
|
||||
.userInfoMapper(userInfoMapper) <7>
|
||||
)
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `userInfoRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract an https://openid.net/specs/openid-connect-core-1_0.html#UserInfoRequest[UserInfo request] from `HttpServletRequest` to an instance of `OidcUserInfoAuthenticationToken`.
|
||||
<2> `userInfoRequestConverters()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationConverter``'s allowing the ability to add, remove, or customize a specific `AuthenticationConverter`.
|
||||
<3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OidcUserInfoAuthenticationToken`.
|
||||
<4> `authenticationProviders()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationProvider``'s allowing the ability to add, remove, or customize a specific `AuthenticationProvider`.
|
||||
<5> `userInfoResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OidcUserInfoAuthenticationToken` and returning the https://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse[UserInfo response].
|
||||
<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the https://openid.net/specs/openid-connect-core-1_0.html#UserInfoError[UserInfo Error response].
|
||||
<7> `userInfoMapper()`: The `Function` used to extract claims from `OidcUserInfoAuthenticationContext` to an instance of `OidcUserInfo`.
|
||||
|
||||
`OidcUserInfoEndpointConfigurer` configures the `OidcUserInfoEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`OidcUserInfoEndpointFilter` is the `Filter` that processes https://openid.net/specs/openid-connect-core-1_0.html#UserInfoRequest[UserInfo requests] and returns the https://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse[OidcUserInfo response].
|
||||
|
||||
`OidcUserInfoEndpointFilter` is configured with the following defaults:
|
||||
|
||||
* `*AuthenticationConverter*` -- An internal implementation that obtains the `Authentication` from the `SecurityContext` and creates an `OidcUserInfoAuthenticationToken` with the principal.
|
||||
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OidcUserInfoAuthenticationProvider`, which is associated with an internal implementation of `userInfoMapper` that extracts https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims[standard claims] from the https://openid.net/specs/openid-connect-core-1_0.html#IDToken[ID Token] based on the https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims[scopes requested] during authorization.
|
||||
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OidcUserInfoAuthenticationToken` and returns the `OidcUserInfo` response.
|
||||
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
|
||||
|
||||
[TIP]
|
||||
You can customize the ID Token by providing an xref:core-model-components.adoc#oauth2-token-customizer[`OAuth2TokenCustomizer<JwtEncodingContext>`] `@Bean`.
|
||||
|
||||
The OpenID Connect 1.0 UserInfo endpoint is an OAuth2 protected resource, which *REQUIRES* an access token to be sent as a bearer token in the https://openid.net/specs/openid-connect-core-1_0.html#UserInfoRequest[UserInfo request].
|
||||
The following example shows how to enable the OAuth2 resource server configuration:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
...
|
||||
|
||||
http.oauth2ResourceServer(resourceServer -> resourceServer.jwt(Customizer.withDefaults()));
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
|
||||
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
A `JwtDecoder` `@Bean` is *REQUIRED* for the OpenID Connect 1.0 UserInfo endpoint.
|
||||
|
||||
[TIP]
|
||||
The guide xref:guides/how-to-userinfo.adoc[How-to: Customize the OpenID Connect 1.0 UserInfo response] contains examples of customizing the UserInfo endpoint.
|
||||
|
||||
[[oidc-client-registration-endpoint]]
|
||||
== OpenID Connect 1.0 Client Registration Endpoint
|
||||
|
||||
`OidcClientRegistrationEndpointConfigurer` provides the ability to customize the https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration[OpenID Connect 1.0 Client Registration endpoint].
|
||||
It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest[Client Registration requests] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadRequest[Client Read requests].
|
||||
|
||||
`OidcClientRegistrationEndpointConfigurer` provides the following configuration options:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
authorizationServerConfigurer
|
||||
.oidc(oidc ->
|
||||
oidc
|
||||
.clientRegistrationEndpoint(clientRegistrationEndpoint ->
|
||||
clientRegistrationEndpoint
|
||||
.clientRegistrationRequestConverter(clientRegistrationRequestConverter) <1>
|
||||
.clientRegistrationRequestConverters(clientRegistrationRequestConvertersConsumers) <2>
|
||||
.authenticationProvider(authenticationProvider) <3>
|
||||
.authenticationProviders(authenticationProvidersConsumer) <4>
|
||||
.clientRegistrationResponseHandler(clientRegistrationResponseHandler) <5>
|
||||
.errorResponseHandler(errorResponseHandler) <6>
|
||||
)
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
----
|
||||
<1> `clientRegistrationRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract a https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest[Client Registration request] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadRequest[Client Read request] from `HttpServletRequest` to an instance of `OidcClientRegistrationAuthenticationToken`.
|
||||
<2> `clientRegistrationRequestConverters()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationConverter``'s allowing the ability to add, remove, or customize a specific `AuthenticationConverter`.
|
||||
<3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OidcClientRegistrationAuthenticationToken`.
|
||||
<4> `authenticationProviders()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationProvider``'s allowing the ability to add, remove, or customize a specific `AuthenticationProvider`.
|
||||
<5> `clientRegistrationResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OidcClientRegistrationAuthenticationToken` and returning the https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse[Client Registration response] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadResponse[Client Read response].
|
||||
<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError[Client Registration Error response] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadError[Client Read Error response].
|
||||
|
||||
[NOTE]
|
||||
The OpenID Connect 1.0 Client Registration endpoint is disabled by default because many deployments do not require dynamic client registration.
|
||||
|
||||
`OidcClientRegistrationEndpointConfigurer` configures the `OidcClientRegistrationEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
|
||||
`OidcClientRegistrationEndpointFilter` is the `Filter` that processes https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest[Client Registration requests] and returns the https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse[OidcClientRegistration response].
|
||||
|
||||
[TIP]
|
||||
`OidcClientRegistrationEndpointFilter` also processes https://openid.net/specs/openid-connect-registration-1_0.html#ReadRequest[Client Read requests] and returns the https://openid.net/specs/openid-connect-registration-1_0.html#ReadResponse[OidcClientRegistration response].
|
||||
|
||||
`OidcClientRegistrationEndpointFilter` is configured with the following defaults:
|
||||
|
||||
* `*AuthenticationConverter*` -- An `OidcClientRegistrationAuthenticationConverter`.
|
||||
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OidcClientRegistrationAuthenticationProvider` and `OidcClientConfigurationAuthenticationProvider`.
|
||||
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OidcClientRegistrationAuthenticationToken` and returns the `OidcClientRegistration` response.
|
||||
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
|
||||
|
||||
The OpenID Connect 1.0 Client Registration endpoint is an https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration[OAuth2 protected resource], which *REQUIRES* an access token to be sent as a bearer token in the Client Registration (or Client Read) request.
|
||||
|
||||
[IMPORTANT]
|
||||
The access token in a Client Registration request *REQUIRES* the OAuth2 scope `client.create`.
|
||||
|
||||
[IMPORTANT]
|
||||
The access token in a Client Read request *REQUIRES* the OAuth2 scope `client.read`.
|
||||
|
||||
The following example shows how to enable the OAuth2 resource server configuration:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
|
||||
new OAuth2AuthorizationServerConfigurer();
|
||||
http.apply(authorizationServerConfigurer);
|
||||
|
||||
...
|
||||
|
||||
http.oauth2ResourceServer(resourceServer -> resourceServer.jwt(Customizer.withDefaults()));
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
|
||||
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
|
||||
}
|
||||
----
|
||||
|
||||
[NOTE]
|
||||
A `JwtDecoder` `@Bean` is *REQUIRED* for the OpenID Connect 1.0 Client Registration endpoint.
|
||||
Reference in New Issue
Block a user