| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 | [[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]----@Beanpublic 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]----@Beanpublic 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]----@Beanpublic 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]----@Beanpublic 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]----@Beanpublic 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]----@Beanpublic 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);			}		});}----
 |