configuration-model.adoc 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. [[oauth2AuthorizationServer-configuration-model]]
  2. = Configuration Model
  3. [[oauth2AuthorizationServer-default-configuration]]
  4. == Default configuration
  5. `OAuth2AuthorizationServerConfiguration` is a `@Configuration` that provides the minimal default configuration for an OAuth2 authorization server.
  6. `OAuth2AuthorizationServerConfiguration` uses xref:servlet/oauth2/authorization-server/configuration-model.adoc#oauth2AuthorizationServer-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.
  7. The OAuth2 authorization server `SecurityFilterChain` `@Bean` is configured with the following default protocol endpoints:
  8. * xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-authorization-endpoint[OAuth2 Authorization endpoint]
  9. * xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-token-endpoint[OAuth2 Token endpoint]
  10. * xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-token-introspection-endpoint[OAuth2 Token Introspection endpoint]
  11. * xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-token-revocation-endpoint[OAuth2 Token Revocation endpoint]
  12. * xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-authorization-server-metadata-endpoint[OAuth2 Authorization Server Metadata endpoint]
  13. * xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-jwk-set-endpoint[JWK Set endpoint]
  14. [NOTE]
  15. The JWK Set endpoint is configured *only* if a `JWKSource<SecurityContext>` `@Bean` is registered.
  16. [NOTE]
  17. ====
  18. The following protocol endpoints are disabled by default:
  19. * xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-device-authorization-endpoint[OAuth2 Device Authorization Endpoint]
  20. * xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-device-verification-endpoint[OAuth2 Device Verification Endpoint]
  21. * xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-client-registration-endpoint[OAuth2 Client Registration endpoint]
  22. ====
  23. The following example shows how to use `OAuth2AuthorizationServerConfiguration` to apply the minimal default configuration:
  24. [source,java]
  25. ----
  26. @Configuration
  27. @Import(OAuth2AuthorizationServerConfiguration.class)
  28. public class AuthorizationServerConfig {
  29. @Bean
  30. public RegisteredClientRepository registeredClientRepository() {
  31. List<RegisteredClient> registrations = ...
  32. return new InMemoryRegisteredClientRepository(registrations);
  33. }
  34. @Bean
  35. public JWKSource<SecurityContext> jwkSource() {
  36. RSAKey rsaKey = ...
  37. JWKSet jwkSet = new JWKSet(rsaKey);
  38. return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
  39. }
  40. }
  41. ----
  42. [IMPORTANT]
  43. 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.
  44. 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`:
  45. [source,java]
  46. ----
  47. @Bean
  48. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  49. http
  50. .oauth2AuthorizationServer((authorizationServer) ->
  51. authorizationServer
  52. .oidc(Customizer.withDefaults()) // Initialize `OidcConfigurer`
  53. );
  54. return http.build();
  55. }
  56. ----
  57. In addition to the default protocol endpoints, the OAuth2 authorization server `SecurityFilterChain` `@Bean` is configured with the following OpenID Connect 1.0 protocol endpoints:
  58. * xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oidc-provider-configuration-endpoint[OpenID Connect 1.0 Provider Configuration endpoint]
  59. * xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oidc-logout-endpoint[OpenID Connect 1.0 Logout endpoint]
  60. * xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint]
  61. [NOTE]
  62. The xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration endpoint] is disabled by default.
  63. [TIP]
  64. `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:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint] and the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration endpoint].
  65. The following example shows how to register a `JwtDecoder` `@Bean`:
  66. [source,java]
  67. ----
  68. @Bean
  69. public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
  70. return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
  71. }
  72. ----
  73. 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.
  74. [[oauth2AuthorizationServer-customizing-the-configuration]]
  75. == Customizing the configuration
  76. `OAuth2AuthorizationServerConfigurer` provides the ability to fully customize the security configuration for an OAuth2 authorization server.
  77. It lets you specify the core components to use - for example, xref:servlet/oauth2/authorization-server/core-model-components.adoc#oauth2AuthorizationServer-registered-client-repository[`RegisteredClientRepository`], xref:servlet/oauth2/authorization-server/core-model-components.adoc#oauth2AuthorizationServer-oauth2-authorization-service[`OAuth2AuthorizationService`], xref:servlet/oauth2/authorization-server/core-model-components.adoc#oauth2AuthorizationServer-oauth2-token-generator[`OAuth2TokenGenerator`], and others.
  78. Furthermore, it lets you customize the request processing logic for the protocol endpoints – for example, xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-authorization-endpoint[authorization endpoint], xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-device-authorization-endpoint[device authorization endpoint], xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-device-verification-endpoint[device verification endpoint], xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-token-endpoint[token endpoint], xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-token-introspection-endpoint[token introspection endpoint], and others.
  79. `OAuth2AuthorizationServerConfigurer` provides the following configuration options:
  80. [source,java]
  81. ----
  82. @Bean
  83. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  84. http
  85. .oauth2AuthorizationServer((authorizationServer) ->
  86. authorizationServer
  87. .registeredClientRepository(registeredClientRepository) <1>
  88. .authorizationService(authorizationService) <2>
  89. .authorizationConsentService(authorizationConsentService) <3>
  90. .authorizationServerSettings(authorizationServerSettings) <4>
  91. .tokenGenerator(tokenGenerator) <5>
  92. .clientAuthentication(clientAuthentication -> { }) <6>
  93. .authorizationEndpoint(authorizationEndpoint -> { }) <7>
  94. .pushedAuthorizationRequestEndpoint(pushedAuthorizationRequestEndpoint -> { }) <8>
  95. .deviceAuthorizationEndpoint(deviceAuthorizationEndpoint -> { }) <9>
  96. .deviceVerificationEndpoint(deviceVerificationEndpoint -> { }) <10>
  97. .tokenEndpoint(tokenEndpoint -> { }) <11>
  98. .tokenIntrospectionEndpoint(tokenIntrospectionEndpoint -> { }) <12>
  99. .tokenRevocationEndpoint(tokenRevocationEndpoint -> { }) <13>
  100. .clientRegistrationEndpoint(clientRegistrationEndpoint -> { }) <14>
  101. .authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint -> { }) <15>
  102. .oidc(oidc -> oidc
  103. .providerConfigurationEndpoint(providerConfigurationEndpoint -> { }) <16>
  104. .logoutEndpoint(logoutEndpoint -> { }) <17>
  105. .userInfoEndpoint(userInfoEndpoint -> { }) <18>
  106. .clientRegistrationEndpoint(clientRegistrationEndpoint -> { }) <19>
  107. )
  108. );
  109. return http.build();
  110. }
  111. ----
  112. <1> `registeredClientRepository()`: The xref:servlet/oauth2/authorization-server/core-model-components.adoc#oauth2AuthorizationServer-registered-client-repository[`RegisteredClientRepository`] (*REQUIRED*) for managing new and existing clients.
  113. <2> `authorizationService()`: The xref:servlet/oauth2/authorization-server/core-model-components.adoc#oauth2AuthorizationServer-oauth2-authorization-service[`OAuth2AuthorizationService`] for managing new and existing authorizations.
  114. <3> `authorizationConsentService()`: The xref:servlet/oauth2/authorization-server/core-model-components.adoc#oauth2AuthorizationServer-oauth2-authorization-consent-service[`OAuth2AuthorizationConsentService`] for managing new and existing authorization consents.
  115. <4> `authorizationServerSettings()`: The xref:servlet/oauth2/authorization-server/configuration-model.adoc#oauth2AuthorizationServer-configuring-authorization-server-settings[`AuthorizationServerSettings`] (*REQUIRED*) for customizing configuration settings for the OAuth2 authorization server.
  116. <5> `tokenGenerator()`: The xref:servlet/oauth2/authorization-server/core-model-components.adoc#oauth2AuthorizationServer-oauth2-token-generator[`OAuth2TokenGenerator`] for generating tokens supported by the OAuth2 authorization server.
  117. <6> `clientAuthentication()`: The configurer for xref:servlet/oauth2/authorization-server/configuration-model.adoc#oauth2AuthorizationServer-configuring-client-authentication[OAuth2 Client Authentication].
  118. <7> `authorizationEndpoint()`: The configurer for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-authorization-endpoint[OAuth2 Authorization endpoint].
  119. <8> `pushedAuthorizationRequestEndpoint()`: The configurer for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-pushed-authorization-request-endpoint[OAuth2 Pushed Authorization Request endpoint].
  120. <9> `deviceAuthorizationEndpoint()`: The configurer for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-device-authorization-endpoint[OAuth2 Device Authorization endpoint].
  121. <10> `deviceVerificationEndpoint()`: The configurer for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-device-verification-endpoint[OAuth2 Device Verification endpoint].
  122. <11> `tokenEndpoint()`: The configurer for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-token-endpoint[OAuth2 Token endpoint].
  123. <12> `tokenIntrospectionEndpoint()`: The configurer for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-token-introspection-endpoint[OAuth2 Token Introspection endpoint].
  124. <13> `tokenRevocationEndpoint()`: The configurer for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-token-revocation-endpoint[OAuth2 Token Revocation endpoint].
  125. <14> `clientRegistrationEndpoint()`: The configurer for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-client-registration-endpoint[OAuth2 Client Registration endpoint].
  126. <15> `authorizationServerMetadataEndpoint()`: The configurer for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-authorization-server-metadata-endpoint[OAuth2 Authorization Server Metadata endpoint].
  127. <16> `providerConfigurationEndpoint()`: The configurer for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oidc-provider-configuration-endpoint[OpenID Connect 1.0 Provider Configuration endpoint].
  128. <17> `logoutEndpoint()`: The configurer for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oidc-logout-endpoint[OpenID Connect 1.0 Logout endpoint].
  129. <18> `userInfoEndpoint()`: The configurer for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oidc-user-info-endpoint[OpenID Connect 1.0 UserInfo endpoint].
  130. <19> `clientRegistrationEndpoint()`: The configurer for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oidc-client-registration-endpoint[OpenID Connect 1.0 Client Registration endpoint].
  131. [[oauth2AuthorizationServer-configuring-authorization-server-settings]]
  132. == Configuring Authorization Server Settings
  133. `AuthorizationServerSettings` contains the configuration settings for the OAuth2 authorization server.
  134. It specifies the `URI` for the protocol endpoints as well as the https://datatracker.ietf.org/doc/html/rfc8414#section-2[issuer identifier].
  135. The default `URI` for the protocol endpoints are as follows:
  136. [source,java]
  137. ----
  138. public final class AuthorizationServerSettings extends AbstractSettings {
  139. ...
  140. public static Builder builder() {
  141. return new Builder()
  142. .authorizationEndpoint("/oauth2/authorize")
  143. .pushedAuthorizationRequestEndpoint("/oauth2/par")
  144. .deviceAuthorizationEndpoint("/oauth2/device_authorization")
  145. .deviceVerificationEndpoint("/oauth2/device_verification")
  146. .tokenEndpoint("/oauth2/token")
  147. .tokenIntrospectionEndpoint("/oauth2/introspect")
  148. .tokenRevocationEndpoint("/oauth2/revoke")
  149. .clientRegistrationEndpoint("/oauth2/register")
  150. .jwkSetEndpoint("/oauth2/jwks")
  151. .oidcLogoutEndpoint("/connect/logout")
  152. .oidcUserInfoEndpoint("/userinfo")
  153. .oidcClientRegistrationEndpoint("/connect/register");
  154. }
  155. ...
  156. }
  157. ----
  158. [NOTE]
  159. `AuthorizationServerSettings` is a *REQUIRED* component.
  160. [TIP]
  161. xref:servlet/oauth2/authorization-server/configuration-model.adoc#oauth2AuthorizationServer-default-configuration[`@Import(OAuth2AuthorizationServerConfiguration.class)`] automatically registers an `AuthorizationServerSettings` `@Bean`, if not already provided.
  162. The following example shows how to customize the configuration settings and register an `AuthorizationServerSettings` `@Bean`:
  163. [source,java]
  164. ----
  165. @Bean
  166. public AuthorizationServerSettings authorizationServerSettings() {
  167. return AuthorizationServerSettings.builder()
  168. .issuer("https://example.com")
  169. .authorizationEndpoint("/oauth2/v1/authorize")
  170. .pushedAuthorizationRequestEndpoint("/oauth2/v1/par")
  171. .deviceAuthorizationEndpoint("/oauth2/v1/device_authorization")
  172. .deviceVerificationEndpoint("/oauth2/v1/device_verification")
  173. .tokenEndpoint("/oauth2/v1/token")
  174. .tokenIntrospectionEndpoint("/oauth2/v1/introspect")
  175. .tokenRevocationEndpoint("/oauth2/v1/revoke")
  176. .clientRegistrationEndpoint("/oauth2/v1/register")
  177. .jwkSetEndpoint("/oauth2/v1/jwks")
  178. .oidcLogoutEndpoint("/connect/v1/logout")
  179. .oidcUserInfoEndpoint("/connect/v1/userinfo")
  180. .oidcClientRegistrationEndpoint("/connect/v1/register")
  181. .build();
  182. }
  183. ----
  184. The `AuthorizationServerContext` is a context object that holds information of the Authorization Server runtime environment.
  185. It provides access to the `AuthorizationServerSettings` and the "`current`" issuer identifier.
  186. [NOTE]
  187. If the issuer identifier is not configured in `AuthorizationServerSettings.builder().issuer(String)`, it is resolved from the current request.
  188. [NOTE]
  189. The `AuthorizationServerContext` is accessible through the `AuthorizationServerContextHolder`, which associates it with the current request thread by using a `ThreadLocal`.
  190. [[oauth2AuthorizationServer-configuring-client-authentication]]
  191. == Configuring Client Authentication
  192. `OAuth2ClientAuthenticationConfigurer` provides the ability to customize https://datatracker.ietf.org/doc/html/rfc6749#section-2.3[OAuth2 client authentication].
  193. It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for client authentication requests.
  194. `OAuth2ClientAuthenticationConfigurer` provides the following configuration options:
  195. [source,java]
  196. ----
  197. @Bean
  198. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  199. http
  200. .oauth2AuthorizationServer((authorizationServer) ->
  201. authorizationServer
  202. .clientAuthentication(clientAuthentication ->
  203. clientAuthentication
  204. .authenticationConverter(authenticationConverter) <1>
  205. .authenticationConverters(authenticationConvertersConsumer) <2>
  206. .authenticationProvider(authenticationProvider) <3>
  207. .authenticationProviders(authenticationProvidersConsumer) <4>
  208. .authenticationSuccessHandler(authenticationSuccessHandler) <5>
  209. .errorResponseHandler(errorResponseHandler) <6>
  210. )
  211. );
  212. return http.build();
  213. }
  214. ----
  215. <1> `authenticationConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract client credentials from `HttpServletRequest` to an instance of `OAuth2ClientAuthenticationToken`.
  216. <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`.
  217. <3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2ClientAuthenticationToken`.
  218. <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`.
  219. <5> `authenticationSuccessHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling a successful client authentication and associating the `OAuth2ClientAuthenticationToken` to the `SecurityContext`.
  220. <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].
  221. `OAuth2ClientAuthenticationConfigurer` configures the `OAuth2ClientAuthenticationFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  222. `OAuth2ClientAuthenticationFilter` is the `Filter` that processes client authentication requests.
  223. By default, client authentication is required for the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-token-endpoint[OAuth2 Token endpoint], the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-token-introspection-endpoint[OAuth2 Token Introspection endpoint], and the xref:servlet/oauth2/authorization-server/protocol-endpoints.adoc#oauth2AuthorizationServer-oauth2-token-revocation-endpoint[OAuth2 Token Revocation endpoint].
  224. The supported client authentication methods are `client_secret_basic`, `client_secret_post`, `private_key_jwt`, `client_secret_jwt`, `tls_client_auth`, `self_signed_tls_client_auth`, and `none` (public clients).
  225. `OAuth2ClientAuthenticationFilter` is configured with the following defaults:
  226. * `*AuthenticationConverter*` -- A `DelegatingAuthenticationConverter` composed of `JwtClientAssertionAuthenticationConverter`, `X509ClientCertificateAuthenticationConverter`, `ClientSecretBasicAuthenticationConverter`, `ClientSecretPostAuthenticationConverter`, and `PublicClientAuthenticationConverter`.
  227. * `*AuthenticationManager*` -- An `AuthenticationManager` composed of `JwtClientAssertionAuthenticationProvider`, `X509ClientCertificateAuthenticationProvider`, `ClientSecretAuthenticationProvider`, and `PublicClientAuthenticationProvider`.
  228. * `*AuthenticationSuccessHandler*` -- An internal implementation that associates the "`authenticated`" `OAuth2ClientAuthenticationToken` (current `Authentication`) to the `SecurityContext`.
  229. * `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` to return the OAuth2 error response.
  230. [[oauth2AuthorizationServer-customizing-jwt-client-assertion-validation]]
  231. === Customizing Jwt Client Assertion Validation
  232. `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.
  233. `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()`.
  234. [NOTE]
  235. `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.
  236. A common use case for customizing `JwtClientAssertionDecoderFactory` is to validate additional claims in the `Jwt` client assertion.
  237. The following example shows how to configure `JwtClientAssertionAuthenticationProvider` with a customized `JwtClientAssertionDecoderFactory` that validates an additional claim in the `Jwt` client assertion:
  238. [source,java]
  239. ----
  240. @Bean
  241. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  242. http
  243. .oauth2AuthorizationServer((authorizationServer) ->
  244. authorizationServer
  245. .clientAuthentication(clientAuthentication ->
  246. clientAuthentication
  247. .authenticationProviders(configureJwtClientAssertionValidator())
  248. )
  249. );
  250. return http.build();
  251. }
  252. private Consumer<List<AuthenticationProvider>> configureJwtClientAssertionValidator() {
  253. return (authenticationProviders) ->
  254. authenticationProviders.forEach((authenticationProvider) -> {
  255. if (authenticationProvider instanceof JwtClientAssertionAuthenticationProvider) {
  256. // Customize JwtClientAssertionDecoderFactory
  257. JwtClientAssertionDecoderFactory jwtDecoderFactory = new JwtClientAssertionDecoderFactory();
  258. Function<RegisteredClient, OAuth2TokenValidator<Jwt>> jwtValidatorFactory = (registeredClient) ->
  259. new DelegatingOAuth2TokenValidator<>(
  260. // Use default validators
  261. JwtClientAssertionDecoderFactory.DEFAULT_JWT_VALIDATOR_FACTORY.apply(registeredClient),
  262. // Add custom validator
  263. new JwtClaimValidator<>("claim", "value"::equals));
  264. jwtDecoderFactory.setJwtValidatorFactory(jwtValidatorFactory);
  265. ((JwtClientAssertionAuthenticationProvider) authenticationProvider)
  266. .setJwtDecoderFactory(jwtDecoderFactory);
  267. }
  268. });
  269. }
  270. ----
  271. [[oauth2AuthorizationServer-customizing-mutual-tls-client-authentication]]
  272. === Customizing Mutual-TLS Client Authentication
  273. `X509ClientCertificateAuthenticationProvider` is used for authenticating the client `X509Certificate` chain received when `ClientAuthenticationMethod.TLS_CLIENT_AUTH` or `ClientAuthenticationMethod.SELF_SIGNED_TLS_CLIENT_AUTH` method is used during OAuth2 client authentication.
  274. It is also composed with a _"Certificate Verifier"_, which is used to verify the contents of the client `X509Certificate` after the TLS handshake has successfully completed.
  275. [[oauth2AuthorizationServer-customizing-mutual-tls-client-authentication-pki-mutual-tls-method]]
  276. ==== PKI Mutual-TLS Method
  277. For the PKI Mutual-TLS (`ClientAuthenticationMethod.TLS_CLIENT_AUTH`) method, the default implementation of the certificate verifier verifies the subject distinguished name of the client `X509Certificate` against the setting `RegisteredClient.getClientSettings.getX509CertificateSubjectDN()`.
  278. If you need to verify another attribute of the client `X509Certificate`, for example, a Subject Alternative Name (SAN) entry, the following example shows how to configure `X509ClientCertificateAuthenticationProvider` with a custom implementation of a certificate verifier:
  279. [source,java]
  280. ----
  281. @Bean
  282. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  283. http
  284. .oauth2AuthorizationServer((authorizationServer) ->
  285. authorizationServer
  286. .clientAuthentication(clientAuthentication ->
  287. clientAuthentication
  288. .authenticationProviders(configureX509ClientCertificateVerifier())
  289. )
  290. );
  291. return http.build();
  292. }
  293. private Consumer<List<AuthenticationProvider>> configureX509ClientCertificateVerifier() {
  294. return (authenticationProviders) ->
  295. authenticationProviders.forEach((authenticationProvider) -> {
  296. if (authenticationProvider instanceof X509ClientCertificateAuthenticationProvider) {
  297. Consumer<OAuth2ClientAuthenticationContext> certificateVerifier = (clientAuthenticationContext) -> {
  298. OAuth2ClientAuthenticationToken clientAuthentication = clientAuthenticationContext.getAuthentication();
  299. RegisteredClient registeredClient = clientAuthenticationContext.getRegisteredClient();
  300. X509Certificate[] clientCertificateChain = (X509Certificate[]) clientAuthentication.getCredentials();
  301. X509Certificate clientCertificate = clientCertificateChain[0];
  302. // TODO Verify Subject Alternative Name (SAN) entry
  303. };
  304. ((X509ClientCertificateAuthenticationProvider) authenticationProvider)
  305. .setCertificateVerifier(certificateVerifier);
  306. }
  307. });
  308. }
  309. ----
  310. [[oauth2AuthorizationServer-customizing-mutual-tls-client-authentication-self-signed-certificate-mutual-tls-method]]
  311. ==== Self-Signed Certificate Mutual-TLS Method
  312. For the Self-Signed Certificate Mutual-TLS (`ClientAuthenticationMethod.SELF_SIGNED_TLS_CLIENT_AUTH`) method, the default implementation of the certificate verifier will retrieve the client's JSON Web Key Set using the setting `RegisteredClient.getClientSettings.getJwkSetUrl()` and expect to find a match against the client `X509Certificate` received during the TLS handshake.
  313. [NOTE]
  314. The `RegisteredClient.getClientSettings.getJwkSetUrl()` setting is used to retrieve the client's certificates via a JSON Web Key (JWK) Set.
  315. A certificate is represented with the `x5c` parameter of an individual JWK within the set.
  316. [[oauth2AuthorizationServer-customizing-mutual-tls-client-authentication-client-certificate-bound-access-tokens]]
  317. ==== Client Certificate-Bound Access Tokens
  318. When Mutual-TLS client authentication is used at the token endpoint, the authorization server is able to bind the issued access token to the client's `X509Certificate`.
  319. The binding is accomplished by computing the SHA-256 thumbprint of the client's `X509Certificate` and associating the thumbprint with the access token.
  320. For example, a JWT access token would include a `x5t#S256` claim, containing the `X509Certificate` thumbprint, within the top-level `cnf` (confirmation method) claim.
  321. Binding the access token to the client's `X509Certificate` provides the ability to implement a proof-of-possession mechanism during protected resource access.
  322. For example, the protected resource would obtain the client's `X509Certificate` used during Mutual-TLS authentication and then verify that the certificate thumbprint matches the `x5t#S256` claim associated with the access token.
  323. The following example shows how to enable certificate-bound access tokens for a client:
  324. [source,java]
  325. ----
  326. RegisteredClient mtlsClient = RegisteredClient.withId(UUID.randomUUID().toString())
  327. .clientId("mtls-client")
  328. .clientAuthenticationMethod(ClientAuthenticationMethod.TLS_CLIENT_AUTH)
  329. .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
  330. .scope("scope-a")
  331. .clientSettings(
  332. ClientSettings.builder()
  333. .x509CertificateSubjectDN("CN=mtls-client,OU=Spring Samples,O=Spring,C=US")
  334. .build()
  335. )
  336. .tokenSettings(
  337. TokenSettings.builder()
  338. .x509CertificateBoundAccessTokens(true)
  339. .build()
  340. )
  341. .build();
  342. ----