protocol-endpoints.adoc 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977
  1. [[oauth2AuthorizationServer-protocol-endpoints]]
  2. = Protocol Endpoints
  3. [[oauth2AuthorizationServer-oauth2-authorization-endpoint]]
  4. == OAuth2 Authorization Endpoint
  5. `OAuth2AuthorizationEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc6749#section-3.1[OAuth2 Authorization endpoint].
  6. 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].
  7. `OAuth2AuthorizationEndpointConfigurer` provides the following configuration options:
  8. [source,java]
  9. ----
  10. @Bean
  11. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  12. http
  13. .oauth2AuthorizationServer((authorizationServer) ->
  14. authorizationServer
  15. .authorizationEndpoint(authorizationEndpoint ->
  16. authorizationEndpoint
  17. .authorizationRequestConverter(authorizationRequestConverter) <1>
  18. .authorizationRequestConverters(authorizationRequestConvertersConsumer) <2>
  19. .authenticationProvider(authenticationProvider) <3>
  20. .authenticationProviders(authenticationProvidersConsumer) <4>
  21. .authorizationResponseHandler(authorizationResponseHandler) <5>
  22. .errorResponseHandler(errorResponseHandler) <6>
  23. .consentPage("/oauth2/v1/authorize") <7>
  24. )
  25. );
  26. return http.build();
  27. }
  28. ----
  29. <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`.
  30. <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`.
  31. <3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2AuthorizationCodeRequestAuthenticationToken` or `OAuth2AuthorizationConsentAuthenticationToken`.
  32. <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`.
  33. <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].
  34. <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].
  35. <7> `consentPage()`: The `URI` of the custom consent page to redirect resource owners to if consent is required during the authorization request flow.
  36. `OAuth2AuthorizationEndpointConfigurer` configures the `OAuth2AuthorizationEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  37. `OAuth2AuthorizationEndpointFilter` is the `Filter` that processes OAuth2 authorization requests (and consents).
  38. `OAuth2AuthorizationEndpointFilter` is configured with the following defaults:
  39. * `*AuthenticationConverter*` -- A `DelegatingAuthenticationConverter` composed of `OAuth2AuthorizationCodeRequestAuthenticationConverter` and `OAuth2AuthorizationConsentAuthenticationConverter`.
  40. * `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2AuthorizationCodeRequestAuthenticationProvider` and `OAuth2AuthorizationConsentAuthenticationProvider`.
  41. * `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OAuth2AuthorizationCodeRequestAuthenticationToken` and returns the `OAuth2AuthorizationResponse`.
  42. * `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthorizationCodeRequestAuthenticationException` and returns the `OAuth2Error` response.
  43. [[oauth2AuthorizationServer-oauth2-authorization-endpoint-customizing-authorization-request-validation]]
  44. === Customizing Authorization Request Validation
  45. `OAuth2AuthorizationCodeRequestAuthenticationValidator` is the default validator used for validating specific OAuth2 authorization request parameters used in the Authorization Code Grant.
  46. The default implementation validates the `redirect_uri` and `scope` parameters.
  47. If validation fails, an `OAuth2AuthorizationCodeRequestAuthenticationException` is thrown.
  48. `OAuth2AuthorizationCodeRequestAuthenticationProvider` provides the ability to override the default authorization request validation by supplying a custom authentication validator of type `Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext>` to `setAuthenticationValidator()`.
  49. [TIP]
  50. `OAuth2AuthorizationCodeRequestAuthenticationContext` holds the `OAuth2AuthorizationCodeRequestAuthenticationToken`, which contains the OAuth2 authorization request parameters.
  51. [IMPORTANT]
  52. If validation fails, the authentication validator *MUST* throw `OAuth2AuthorizationCodeRequestAuthenticationException`.
  53. A common use case during the development life cycle phase is to allow for `localhost` in the `redirect_uri` parameter.
  54. The following example shows how to configure `OAuth2AuthorizationCodeRequestAuthenticationProvider` with a custom authentication validator that allows for `localhost` in the `redirect_uri` parameter:
  55. [source,java]
  56. ----
  57. @Bean
  58. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  59. http
  60. .oauth2AuthorizationServer((authorizationServer) ->
  61. authorizationServer
  62. .authorizationEndpoint(authorizationEndpoint ->
  63. authorizationEndpoint
  64. .authenticationProviders(configureAuthenticationValidator())
  65. )
  66. );
  67. return http.build();
  68. }
  69. private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
  70. return (authenticationProviders) ->
  71. authenticationProviders.forEach((authenticationProvider) -> {
  72. if (authenticationProvider instanceof OAuth2AuthorizationCodeRequestAuthenticationProvider) {
  73. Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> authenticationValidator =
  74. // Override default redirect_uri validator
  75. new CustomRedirectUriValidator()
  76. // Reuse default scope validator
  77. .andThen(OAuth2AuthorizationCodeRequestAuthenticationValidator.DEFAULT_SCOPE_VALIDATOR);
  78. ((OAuth2AuthorizationCodeRequestAuthenticationProvider) authenticationProvider)
  79. .setAuthenticationValidator(authenticationValidator);
  80. }
  81. });
  82. }
  83. static class CustomRedirectUriValidator implements Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> {
  84. @Override
  85. public void accept(OAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext) {
  86. OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication =
  87. authenticationContext.getAuthentication();
  88. RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
  89. String requestedRedirectUri = authorizationCodeRequestAuthentication.getRedirectUri();
  90. // Use exact string matching when comparing client redirect URIs against pre-registered URIs
  91. if (!registeredClient.getRedirectUris().contains(requestedRedirectUri)) {
  92. OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST);
  93. throw new OAuth2AuthorizationCodeRequestAuthenticationException(error, null);
  94. }
  95. }
  96. }
  97. ----
  98. [[oauth2AuthorizationServer-oauth2-pushed-authorization-request-endpoint]]
  99. == OAuth2 Pushed Authorization Request Endpoint
  100. `OAuth2PushedAuthorizationRequestEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc9126#section-2[OAuth2 Pushed Authorization Request endpoint].
  101. It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for https://datatracker.ietf.org/doc/html/rfc9126#section-2.1[OAuth2 Pushed Authorization requests].
  102. `OAuth2PushedAuthorizationRequestEndpointConfigurer` provides the following configuration options:
  103. [source,java]
  104. ----
  105. @Bean
  106. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  107. http
  108. .oauth2AuthorizationServer((authorizationServer) ->
  109. authorizationServer
  110. .pushedAuthorizationRequestEndpoint(pushedAuthorizationRequestEndpoint ->
  111. pushedAuthorizationRequestEndpoint
  112. .pushedAuthorizationRequestConverter(pushedAuthorizationRequestConverter) <1>
  113. .pushedAuthorizationRequestConverters(pushedAuthorizationRequestConvertersConsumer) <2>
  114. .authenticationProvider(authenticationProvider) <3>
  115. .authenticationProviders(authenticationProvidersConsumer) <4>
  116. .pushedAuthorizationResponseHandler(pushedAuthorizationResponseHandler) <5>
  117. .errorResponseHandler(errorResponseHandler) <6>
  118. )
  119. );
  120. return http.build();
  121. }
  122. ----
  123. <1> `pushedAuthorizationRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract an https://datatracker.ietf.org/doc/html/rfc9126#section-2.1[OAuth2 pushed authorization request] from `HttpServletRequest` to an instance of `OAuth2PushedAuthorizationRequestAuthenticationToken`.
  124. <2> `pushedAuthorizationRequestConverters()`: 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`.
  125. <3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2PushedAuthorizationRequestAuthenticationToken`.
  126. <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`.
  127. <5> `pushedAuthorizationResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OAuth2PushedAuthorizationRequestAuthenticationToken` and returning the https://datatracker.ietf.org/doc/html/rfc9126#section-2.2[OAuth2 pushed authorization response].
  128. <6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the https://datatracker.ietf.org/doc/html/rfc9126#section-2.3[OAuth2Error response].
  129. `OAuth2PushedAuthorizationRequestEndpointConfigurer` configures the `OAuth2PushedAuthorizationRequestEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  130. `OAuth2PushedAuthorizationRequestEndpointFilter` is the `Filter` that processes OAuth2 pushed authorization requests.
  131. `OAuth2PushedAuthorizationRequestEndpointFilter` is configured with the following defaults:
  132. * `*AuthenticationConverter*` -- A `DelegatingAuthenticationConverter` composed of `OAuth2AuthorizationCodeRequestAuthenticationConverter`.
  133. * `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2PushedAuthorizationRequestAuthenticationProvider`.
  134. * `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OAuth2PushedAuthorizationRequestAuthenticationToken` and returns the OAuth2 pushed authorization response.
  135. * `*AuthenticationFailureHandler*` -- An `OAuth2ErrorAuthenticationFailureHandler`.
  136. [[oauth2AuthorizationServer-oauth2-pushed-authorization-request-endpoint-customizing-pushed-authorization-request-validation]]
  137. === Customizing Pushed Authorization Request Validation
  138. `OAuth2AuthorizationCodeRequestAuthenticationValidator` is the default validator used for validating specific OAuth2 pushed authorization request parameters used in the Authorization Code Grant.
  139. The default implementation validates the `redirect_uri` and `scope` parameters.
  140. If validation fails, an `OAuth2AuthorizationCodeRequestAuthenticationException` is thrown.
  141. `OAuth2PushedAuthorizationRequestAuthenticationProvider` provides the ability to override the default pushed authorization request validation by supplying a custom authentication validator of type `Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext>` to `setAuthenticationValidator()`.
  142. [TIP]
  143. `OAuth2AuthorizationCodeRequestAuthenticationContext` holds the `OAuth2AuthorizationCodeRequestAuthenticationToken`, which contains the OAuth2 pushed authorization request parameters.
  144. [IMPORTANT]
  145. If validation fails, the authentication validator *MUST* throw `OAuth2AuthorizationCodeRequestAuthenticationException`.
  146. A common use case during the development life cycle phase is to allow for `localhost` in the `redirect_uri` parameter.
  147. The following example shows how to configure `OAuth2PushedAuthorizationRequestAuthenticationProvider` with a custom authentication validator that allows for `localhost` in the `redirect_uri` parameter:
  148. [source,java]
  149. ----
  150. @Bean
  151. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  152. http
  153. .oauth2AuthorizationServer((authorizationServer) ->
  154. authorizationServer
  155. .pushedAuthorizationRequestEndpoint(pushedAuthorizationRequestEndpoint ->
  156. pushedAuthorizationRequestEndpoint
  157. .authenticationProviders(configureAuthenticationValidator())
  158. )
  159. );
  160. return http.build();
  161. }
  162. private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
  163. return (authenticationProviders) ->
  164. authenticationProviders.forEach((authenticationProvider) -> {
  165. if (authenticationProvider instanceof OAuth2PushedAuthorizationRequestAuthenticationProvider) {
  166. Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> authenticationValidator =
  167. // Override default redirect_uri validator
  168. new CustomRedirectUriValidator()
  169. // Reuse default scope validator
  170. .andThen(OAuth2AuthorizationCodeRequestAuthenticationValidator.DEFAULT_SCOPE_VALIDATOR);
  171. ((OAuth2PushedAuthorizationRequestAuthenticationProvider) authenticationProvider)
  172. .setAuthenticationValidator(authenticationValidator);
  173. }
  174. });
  175. }
  176. static class CustomRedirectUriValidator implements Consumer<OAuth2AuthorizationCodeRequestAuthenticationContext> {
  177. @Override
  178. public void accept(OAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext) {
  179. OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication =
  180. authenticationContext.getAuthentication();
  181. RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
  182. String requestedRedirectUri = authorizationCodeRequestAuthentication.getRedirectUri();
  183. // Use exact string matching when comparing client redirect URIs against pre-registered URIs
  184. if (!registeredClient.getRedirectUris().contains(requestedRedirectUri)) {
  185. OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST);
  186. throw new OAuth2AuthorizationCodeRequestAuthenticationException(error, null);
  187. }
  188. }
  189. }
  190. ----
  191. [[oauth2AuthorizationServer-oauth2-device-authorization-endpoint]]
  192. == OAuth2 Device Authorization Endpoint
  193. `OAuth2DeviceAuthorizationEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc8628#section-3.1[OAuth2 Device Authorization endpoint].
  194. It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for OAuth2 device authorization requests.
  195. `OAuth2DeviceAuthorizationEndpointConfigurer` provides the following configuration options:
  196. [source,java]
  197. ----
  198. @Bean
  199. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  200. http
  201. .oauth2AuthorizationServer((authorizationServer) ->
  202. authorizationServer
  203. .deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
  204. deviceAuthorizationEndpoint
  205. .deviceAuthorizationRequestConverter(deviceAuthorizationRequestConverter) <1>
  206. .deviceAuthorizationRequestConverters(deviceAuthorizationRequestConvertersConsumer) <2>
  207. .authenticationProvider(authenticationProvider) <3>
  208. .authenticationProviders(authenticationProvidersConsumer) <4>
  209. .deviceAuthorizationResponseHandler(deviceAuthorizationResponseHandler) <5>
  210. .errorResponseHandler(errorResponseHandler) <6>
  211. .verificationUri("/oauth2/v1/device_verification") <7>
  212. )
  213. );
  214. return http.build();
  215. }
  216. ----
  217. <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`.
  218. <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`.
  219. <3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2DeviceAuthorizationRequestAuthenticationToken`.
  220. <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`.
  221. <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].
  222. <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].
  223. <7> `verificationUri()`: The `URI` of the custom end-user verification page to direct resource owners to on a secondary device.
  224. `OAuth2DeviceAuthorizationEndpointConfigurer` configures the `OAuth2DeviceAuthorizationEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  225. `OAuth2DeviceAuthorizationEndpointFilter` is the `Filter` that processes OAuth2 device authorization requests.
  226. `OAuth2DeviceAuthorizationEndpointFilter` is configured with the following defaults:
  227. * `*AuthenticationConverter*` -- An `OAuth2DeviceAuthorizationRequestAuthenticationConverter`.
  228. * `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2DeviceAuthorizationRequestAuthenticationProvider`.
  229. * `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OAuth2DeviceAuthorizationRequestAuthenticationToken` and returns the `OAuth2DeviceAuthorizationResponse`.
  230. * `*AuthenticationFailureHandler*` -- An `OAuth2ErrorAuthenticationFailureHandler`.
  231. [[oauth2AuthorizationServer-oauth2-device-verification-endpoint]]
  232. == OAuth2 Device Verification Endpoint
  233. `OAuth2DeviceVerificationEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc8628#section-3.3[OAuth2 Device Verification endpoint] (or "User Interaction").
  234. It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for OAuth2 device verification requests.
  235. `OAuth2DeviceVerificationEndpointConfigurer` provides the following configuration options:
  236. [source,java]
  237. ----
  238. @Bean
  239. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  240. http
  241. .oauth2AuthorizationServer((authorizationServer) ->
  242. authorizationServer
  243. .deviceVerificationEndpoint(deviceVerificationEndpoint ->
  244. deviceVerificationEndpoint
  245. .deviceVerificationRequestConverter(deviceVerificationRequestConverter) <1>
  246. .deviceVerificationRequestConverters(deviceVerificationRequestConvertersConsumer) <2>
  247. .authenticationProvider(authenticationProvider) <3>
  248. .authenticationProviders(authenticationProvidersConsumer) <4>
  249. .deviceVerificationResponseHandler(deviceVerificationResponseHandler) <5>
  250. .errorResponseHandler(errorResponseHandler) <6>
  251. .consentPage("/oauth2/v1/consent") <7>
  252. )
  253. );
  254. return http.build();
  255. }
  256. ----
  257. <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`.
  258. <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`.
  259. <3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2DeviceVerificationAuthenticationToken` or `OAuth2DeviceAuthorizationConsentAuthenticationToken`.
  260. <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`.
  261. <5> `deviceVerificationResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OAuth2DeviceVerificationAuthenticationToken` and directing the resource owner to return to their device.
  262. <6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the error response.
  263. <7> `consentPage()`: The `URI` of the custom consent page to redirect resource owners to if consent is required during the device verification request flow.
  264. `OAuth2DeviceVerificationEndpointConfigurer` configures the `OAuth2DeviceVerificationEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  265. `OAuth2DeviceVerificationEndpointFilter` is the `Filter` that processes OAuth2 device verification requests (and consents).
  266. `OAuth2DeviceVerificationEndpointFilter` is configured with the following defaults:
  267. * `*AuthenticationConverter*` -- A `DelegatingAuthenticationConverter` composed of `OAuth2DeviceVerificationAuthenticationConverter` and `OAuth2DeviceAuthorizationConsentAuthenticationConverter`.
  268. * `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2DeviceVerificationAuthenticationProvider` and `OAuth2DeviceAuthorizationConsentAuthenticationProvider`.
  269. * `*AuthenticationSuccessHandler*` -- A `SimpleUrlAuthenticationSuccessHandler` that handles an "`authenticated`" `OAuth2DeviceVerificationAuthenticationToken` and redirects the user to a success page (`/?success`).
  270. * `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
  271. [[oauth2AuthorizationServer-oauth2-token-endpoint]]
  272. == OAuth2 Token Endpoint
  273. `OAuth2TokenEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc6749#section-3.2[OAuth2 Token endpoint].
  274. 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].
  275. `OAuth2TokenEndpointConfigurer` provides the following configuration options:
  276. [source,java]
  277. ----
  278. @Bean
  279. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  280. http
  281. .oauth2AuthorizationServer((authorizationServer) ->
  282. authorizationServer
  283. .tokenEndpoint(tokenEndpoint ->
  284. tokenEndpoint
  285. .accessTokenRequestConverter(accessTokenRequestConverter) <1>
  286. .accessTokenRequestConverters(accessTokenRequestConvertersConsumer) <2>
  287. .authenticationProvider(authenticationProvider) <3>
  288. .authenticationProviders(authenticationProvidersConsumer) <4>
  289. .accessTokenResponseHandler(accessTokenResponseHandler) <5>
  290. .errorResponseHandler(errorResponseHandler) <6>
  291. )
  292. );
  293. return http.build();
  294. }
  295. ----
  296. <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`.
  297. <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`.
  298. <3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2AuthorizationGrantAuthenticationToken`.
  299. <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`.
  300. <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`].
  301. <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].
  302. `OAuth2TokenEndpointConfigurer` configures the `OAuth2TokenEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  303. `OAuth2TokenEndpointFilter` is the `Filter` that processes OAuth2 access token requests.
  304. The supported https://datatracker.ietf.org/doc/html/rfc6749#section-1.3[authorization grant types] are `authorization_code`, `refresh_token`, `client_credentials`, `urn:ietf:params:oauth:grant-type:device_code`, and `urn:ietf:params:oauth:grant-type:token-exchange`.
  305. `OAuth2TokenEndpointFilter` is configured with the following defaults:
  306. * `*AuthenticationConverter*` -- A `DelegatingAuthenticationConverter` composed of `OAuth2AuthorizationCodeAuthenticationConverter`, `OAuth2RefreshTokenAuthenticationConverter`, `OAuth2ClientCredentialsAuthenticationConverter`, `OAuth2DeviceCodeAuthenticationConverter`, and `OAuth2TokenExchangeAuthenticationConverter`.
  307. * `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2AuthorizationCodeAuthenticationProvider`, `OAuth2RefreshTokenAuthenticationProvider`, `OAuth2ClientCredentialsAuthenticationProvider`, `OAuth2DeviceCodeAuthenticationProvider`, and `OAuth2TokenExchangeAuthenticationProvider`.
  308. * `*AuthenticationSuccessHandler*` -- An `OAuth2AccessTokenResponseAuthenticationSuccessHandler`.
  309. * `*AuthenticationFailureHandler*` -- An `OAuth2ErrorAuthenticationFailureHandler`.
  310. [[oauth2AuthorizationServer-oauth2-token-endpoint-customizing-client-credentials-grant-request-validation]]
  311. === Customizing Client Credentials Grant Request Validation
  312. `OAuth2ClientCredentialsAuthenticationValidator` is the default validator used for validating specific OAuth2 Client Credentials Grant request parameters.
  313. The default implementation validates the `scope` parameter.
  314. If validation fails, an `OAuth2AuthenticationException` is thrown.
  315. `OAuth2ClientCredentialsAuthenticationProvider` provides the ability to override the default request validation by supplying a custom authentication validator of type `Consumer<OAuth2ClientCredentialsAuthenticationContext>` to `setAuthenticationValidator()`.
  316. [TIP]
  317. `OAuth2ClientCredentialsAuthenticationContext` holds the `OAuth2ClientCredentialsAuthenticationToken`, which contains the OAuth2 Client Credentials Grant request parameters.
  318. [IMPORTANT]
  319. If validation fails, the authentication validator *MUST* throw `OAuth2AuthenticationException`.
  320. The following example shows how to configure `OAuth2ClientCredentialsAuthenticationProvider` with a custom authentication validator that overrides the default `scope` validation:
  321. [source,java]
  322. ----
  323. @Bean
  324. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  325. http
  326. .oauth2AuthorizationServer((authorizationServer) ->
  327. authorizationServer
  328. .tokenEndpoint(tokenEndpoint ->
  329. tokenEndpoint
  330. .authenticationProviders(configureAuthenticationValidator())
  331. )
  332. );
  333. return http.build();
  334. }
  335. private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
  336. return (authenticationProviders) ->
  337. authenticationProviders.forEach((authenticationProvider) -> {
  338. if (authenticationProvider instanceof OAuth2ClientCredentialsAuthenticationProvider) {
  339. Consumer<OAuth2ClientCredentialsAuthenticationContext> authenticationValidator =
  340. new CustomScopeValidator();
  341. // Override default scope validation
  342. ((OAuth2ClientCredentialsAuthenticationProvider) authenticationProvider)
  343. .setAuthenticationValidator(authenticationValidator);
  344. }
  345. });
  346. }
  347. static class CustomScopeValidator implements Consumer<OAuth2ClientCredentialsAuthenticationContext> {
  348. @Override
  349. public void accept(OAuth2ClientCredentialsAuthenticationContext authenticationContext) {
  350. OAuth2ClientCredentialsAuthenticationToken clientCredentialsAuthentication =
  351. authenticationContext.getAuthentication();
  352. Set<String> requestedScopes = clientCredentialsAuthentication.getScopes();
  353. RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
  354. Set<String> allowedScopes = registeredClient.getScopes();
  355. // TODO Implement scope validation
  356. }
  357. }
  358. ----
  359. [[oauth2AuthorizationServer-oauth2-token-endpoint-dpop-bound-access-tokens]]
  360. === DPoP-bound Access Tokens
  361. https://datatracker.ietf.org/doc/html/rfc9449[RFC 9449 OAuth 2.0 Demonstrating Proof of Possession (DPoP)] is an application-level mechanism for sender-constraining an access token.
  362. The primary goal of DPoP is to prevent unauthorized or illegitimate clients from using leaked or stolen access tokens, by binding an access token to a public key upon issuance by the authorization server and requiring that the client proves possession of the corresponding private key when using the access token at the resource server.
  363. Access tokens that are sender-constrained via DPoP stand in contrast to the typical bearer token, which can be used by any client in possession of the access token.
  364. DPoP introduces the concept of a https://datatracker.ietf.org/doc/html/rfc9449#name-dpop-proof-jwts[DPoP Proof], which is a JWT created by the client and sent as a header in an HTTP request.
  365. A client uses a DPoP proof to prove the possession of a private key corresponding to a certain public key.
  366. When the client initiates an access token request, it attaches a DPoP proof to the request in an HTTP header.
  367. The authorization server binds (sender-constrains) the access token to the public key associated in the DPoP proof.
  368. When the client initiates a protected resource request, it again attaches a DPoP proof to the request in an HTTP header.
  369. The resource server obtains information about the public key bound to the access token, either directly in the access token (JWT) or via the <<oauth2AuthorizationServer-oauth2-token-introspection-endpoint,OAuth2 Token Introspection endpoint>>.
  370. The resource server then verifies that the public key bound to the access token matches the public key in the DPoP proof.
  371. It also verifies that the access token hash in the DPoP proof matches the access token in the request.
  372. [[oauth2AuthorizationServer-oauth2-token-endpoint-dpop-access-token-request]]
  373. ==== DPoP Access Token Request
  374. To request an access token that is bound to a public key using DPoP, the client MUST provide a valid DPoP proof in the `DPoP` header when making an access token request to the OAuth2 Token endpoint.
  375. This is applicable for all access token requests regardless of authorization grant type (e.g. `authorization_code`, `refresh_token`, `client_credentials`, etc).
  376. The following HTTP request shows an `authorization_code` access token request with a DPoP proof in the `DPoP` header:
  377. [source,shell]
  378. ----
  379. POST /oauth2/token HTTP/1.1
  380. Host: server.example.com
  381. Content-Type: application/x-www-form-urlencoded
  382. DPoP: eyJraWQiOiJyc2EtandrLWtpZCIsInR5cCI6ImRwb3Arand0IiwiYWxnIjoiUlMyNTYiLCJqd2siOnsia3R5IjoiUlNBIiwiZSI6IkFRQUIiLCJraWQiOiJyc2EtandrLWtpZCIsIm4iOiIzRmxxSnI1VFJza0lRSWdkRTNEZDdEOWxib1dkY1RVVDhhLWZKUjdNQXZRbTdYWE5vWWttM3Y3TVFMMU5ZdER2TDJsOENBbmMwV2RTVElOVTZJUnZjNUtxbzJRNGNzTlg5U0hPbUVmem9ST2pRcWFoRWN2ZTFqQlhsdW9DWGRZdVlweDRfMXRmUmdHNmlpNFVoeGg2aUk4cU5NSlFYLWZMZnFoYmZZZnhCUVZSUHl3QmtBYklQNHgxRUFzYkM2RlNObWtoQ3hpTU5xRWd4YUlwWThDMmtKZEpfWklWLVdXNG5vRGR6cEtxSGN3bUI4RnNydW1sVllfRE5WdlVTRElpcGlxOVBiUDRIOTlUWE4xbzc0Nm9SYU5hMDdycTFob0NnTVNTeS04NVNhZ0NveGxteUUtRC1vZjlTc01ZOE9sOXQwcmR6cG9iQnVoeUpfbzVkZnZqS3cifX0.eyJodG0iOiJQT1NUIiwiaHR1IjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20vb2F1dGgyL3Rva2VuIiwiaWF0IjoxNzQ2ODA2MzA1LCJqdGkiOiI0YjIzNDBkMi1hOTFmLTQwYTUtYmFhOS1kZDRlNWRlYWM4NjcifQ.wq8gJ_G6vpiEinfaY3WhereqCCLoeJOG8tnWBBAzRWx9F1KU5yAAWq-ZVCk_k07-h6DIqz2wgv6y9dVbNpRYwNwDUeik9qLRsC60M8YW7EFVyI3n_NpujLwzZeub_nDYMVnyn4ii0NaZrYHtoGXOlswQfS_-ET-jpC0XWm5nBZsCdUEXjOYtwaACC6Js-pyNwKmSLp5SKIk11jZUR5xIIopaQy521y9qJHhGRwzj8DQGsP7wMZ98UFL0E--1c-hh4rTy8PMeWCqRHdwjj_ry_eTe0DJFcxxYQdeL7-0_0CIO4Ayx5WHEpcUOIzBRoN32RsNpDZc-5slDNj9ku004DA
  383. grant_type=authorization_code\
  384. &client_id=s6BhdRkqt\
  385. &code=SplxlOBeZQQYbYS6WxSbIA\
  386. &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb\
  387. &code_verifier=bEaL42izcC-o-xBk0K2vuJ6U-y1p9r_wW2dFWIWgjz-
  388. ----
  389. The following shows a representation of the DPoP Proof JWT header and claims:
  390. [source,json]
  391. ----
  392. {
  393. "typ": "dpop+jwt",
  394. "alg": "RS256",
  395. "jwk": {
  396. "kty": "RSA",
  397. "e": "AQAB",
  398. "n": "3FlqJr5TRskIQIgdE3Dd7D9lboWdcTUT8a-fJR7MAvQm7XXNoYkm3v7MQL1NYtDvL2l8CAnc0WdSTINU6IRvc5Kqo2Q4csNX9SHOmEfzoROjQqahEcve1jBXluoCXdYuYpx4_1tfRgG6ii4Uhxh6iI8qNMJQX-fLfqhbfYfxBQVRPywBkAbIP4x1EAsbC6FSNmkhCxiMNqEgxaIpY8C2kJdJ_ZIV-WW4noDdzpKqHcwmB8FsrumlVY_DNVvUSDIipiq9PbP4H99TXN1o746oRaNa07rq1hoCgMSSy-85SagCoxlmyE-D-of9SsMY8Ol9t0rdzpobBuhyJ_o5dfvjKw"
  399. }
  400. }
  401. ----
  402. [source,json]
  403. ----
  404. {
  405. "htm": "POST",
  406. "htu": "https://server.example.com/oauth2/token",
  407. "iat": 1746806305,
  408. "jti": "4b2340d2-a91f-40a5-baa9-dd4e5deac867"
  409. }
  410. ----
  411. The following code shows an example of how to generate the DPoP Proof JWT:
  412. [source,java]
  413. ----
  414. RSAKey rsaKey = ...
  415. JWKSource<SecurityContext> jwkSource = (jwkSelector, securityContext) -> jwkSelector
  416. .select(new JWKSet(rsaKey));
  417. NimbusJwtEncoder jwtEncoder = new NimbusJwtEncoder(jwkSource);
  418. JwsHeader jwsHeader = JwsHeader.with(SignatureAlgorithm.RS256)
  419. .type("dpop+jwt")
  420. .jwk(rsaKey.toPublicJWK().toJSONObject())
  421. .build();
  422. JwtClaimsSet claims = JwtClaimsSet.builder()
  423. .issuedAt(Instant.now())
  424. .claim("htm", "POST")
  425. .claim("htu", "https://server.example.com/oauth2/token")
  426. .id(UUID.randomUUID().toString())
  427. .build();
  428. Jwt dPoPProof = jwtEncoder.encode(JwtEncoderParameters.from(jwsHeader, claims));
  429. ----
  430. After the authorization server successfully validates the DPoP proof, the public key from the DPoP proof will be bound (sender-constrained) to the issued access token.
  431. The following access token response shows the `token_type` parameter as `DPoP` to signal to the client that the access token was bound to its DPoP proof public key:
  432. [source,shell]
  433. ----
  434. HTTP/1.1 200 OK
  435. Content-Type: application/json
  436. Cache-Control: no-store
  437. {
  438. "access_token": "Kz~8mXK1EalYznwH-LC-1fBAo.4Ljp~zsPE_NeO.gxU",
  439. "token_type": "DPoP",
  440. "expires_in": 2677
  441. }
  442. ----
  443. [[oauth2AuthorizationServer-oauth2-token-endpoint-dpop-public-key-confirmation]]
  444. ==== Public Key Confirmation
  445. Resource servers MUST be able to identify whether an access token is DPoP-bound and verify the binding to the public key of the DPoP proof.
  446. The binding is accomplished by associating the public key with the access token in a way that can be accessed by the resource server, such as embedding the public key hash in the access token directly (JWT) or through token introspection.
  447. When an access token is represented as a JWT, the public key hash is contained in the `jkt` claim under the confirmation method (`cnf`) claim.
  448. The following example shows the claims of a JWT access token containing a `cnf` claim with a `jkt` claim, which is the JWK SHA-256 Thumbprint of the DPoP proof public key:
  449. [source,json]
  450. ----
  451. {
  452. "sub":"user@example.com",
  453. "iss":"https://server.example.com",
  454. "nbf":1562262611,
  455. "exp":1562266216,
  456. "cnf":
  457. {
  458. "jkt":"CQMknzRoZ5YUi7vS58jck1q8TmZT8wiIiXrCN1Ny4VU"
  459. }
  460. }
  461. ----
  462. [[oauth2AuthorizationServer-oauth2-token-introspection-endpoint]]
  463. == OAuth2 Token Introspection Endpoint
  464. `OAuth2TokenIntrospectionEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc7662#section-2[OAuth2 Token Introspection endpoint].
  465. 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].
  466. `OAuth2TokenIntrospectionEndpointConfigurer` provides the following configuration options:
  467. [source,java]
  468. ----
  469. @Bean
  470. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  471. http
  472. .oauth2AuthorizationServer((authorizationServer) ->
  473. authorizationServer
  474. .tokenIntrospectionEndpoint(tokenIntrospectionEndpoint ->
  475. tokenIntrospectionEndpoint
  476. .introspectionRequestConverter(introspectionRequestConverter) <1>
  477. .introspectionRequestConverters(introspectionRequestConvertersConsumer) <2>
  478. .authenticationProvider(authenticationProvider) <3>
  479. .authenticationProviders(authenticationProvidersConsumer) <4>
  480. .introspectionResponseHandler(introspectionResponseHandler) <5>
  481. .errorResponseHandler(errorResponseHandler) <6>
  482. )
  483. );
  484. return http.build();
  485. }
  486. ----
  487. <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`.
  488. <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`.
  489. <3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2TokenIntrospectionAuthenticationToken`.
  490. <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`.
  491. <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].
  492. <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].
  493. `OAuth2TokenIntrospectionEndpointConfigurer` configures the `OAuth2TokenIntrospectionEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  494. `OAuth2TokenIntrospectionEndpointFilter` is the `Filter` that processes OAuth2 introspection requests.
  495. `OAuth2TokenIntrospectionEndpointFilter` is configured with the following defaults:
  496. * `*AuthenticationConverter*` -- An `OAuth2TokenIntrospectionAuthenticationConverter`.
  497. * `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2TokenIntrospectionAuthenticationProvider`.
  498. * `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OAuth2TokenIntrospectionAuthenticationToken` and returns the `OAuth2TokenIntrospection` response.
  499. * `*AuthenticationFailureHandler*` -- An `OAuth2ErrorAuthenticationFailureHandler`.
  500. [[oauth2AuthorizationServer-oauth2-token-revocation-endpoint]]
  501. == OAuth2 Token Revocation Endpoint
  502. `OAuth2TokenRevocationEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc7009#section-2[OAuth2 Token Revocation endpoint].
  503. 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].
  504. `OAuth2TokenRevocationEndpointConfigurer` provides the following configuration options:
  505. [source,java]
  506. ----
  507. @Bean
  508. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  509. http
  510. .oauth2AuthorizationServer((authorizationServer) ->
  511. authorizationServer
  512. .tokenRevocationEndpoint(tokenRevocationEndpoint ->
  513. tokenRevocationEndpoint
  514. .revocationRequestConverter(revocationRequestConverter) <1>
  515. .revocationRequestConverters(revocationRequestConvertersConsumer) <2>
  516. .authenticationProvider(authenticationProvider) <3>
  517. .authenticationProviders(authenticationProvidersConsumer) <4>
  518. .revocationResponseHandler(revocationResponseHandler) <5>
  519. .errorResponseHandler(errorResponseHandler) <6>
  520. )
  521. );
  522. return http.build();
  523. }
  524. ----
  525. <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`.
  526. <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`.
  527. <3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OAuth2TokenRevocationAuthenticationToken`.
  528. <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`.
  529. <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].
  530. <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].
  531. `OAuth2TokenRevocationEndpointConfigurer` configures the `OAuth2TokenRevocationEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  532. `OAuth2TokenRevocationEndpointFilter` is the `Filter` that processes OAuth2 revocation requests.
  533. `OAuth2TokenRevocationEndpointFilter` is configured with the following defaults:
  534. * `*AuthenticationConverter*` -- An `OAuth2TokenRevocationAuthenticationConverter`.
  535. * `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OAuth2TokenRevocationAuthenticationProvider`.
  536. * `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OAuth2TokenRevocationAuthenticationToken` and returns the OAuth2 revocation response.
  537. * `*AuthenticationFailureHandler*` -- An `OAuth2ErrorAuthenticationFailureHandler`.
  538. [[oauth2AuthorizationServer-oauth2-authorization-server-metadata-endpoint]]
  539. == OAuth2 Authorization Server Metadata Endpoint
  540. `OAuth2AuthorizationServerMetadataEndpointConfigurer` provides the ability to customize the https://datatracker.ietf.org/doc/html/rfc8414#section-3[OAuth2 Authorization Server Metadata endpoint].
  541. 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].
  542. `OAuth2AuthorizationServerMetadataEndpointConfigurer` provides the following configuration option:
  543. [source,java]
  544. ----
  545. @Bean
  546. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  547. http
  548. .oauth2AuthorizationServer((authorizationServer) ->
  549. authorizationServer
  550. .authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint ->
  551. authorizationServerMetadataEndpoint
  552. .authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer) <1>
  553. )
  554. );
  555. return http.build();
  556. }
  557. ----
  558. <1> `authorizationServerMetadataCustomizer()`: The `Consumer` providing access to the `OAuth2AuthorizationServerMetadata.Builder` allowing the ability to customize the claims of the Authorization Server's configuration.
  559. `OAuth2AuthorizationServerMetadataEndpointConfigurer` configures the `OAuth2AuthorizationServerMetadataEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  560. `OAuth2AuthorizationServerMetadataEndpointFilter` is the `Filter` that returns the https://datatracker.ietf.org/doc/html/rfc8414#section-3.2[OAuth2AuthorizationServerMetadata response].
  561. [[oauth2AuthorizationServer-jwk-set-endpoint]]
  562. == JWK Set Endpoint
  563. `OAuth2AuthorizationServerConfigurer` provides support for the https://datatracker.ietf.org/doc/html/rfc7517[JWK Set endpoint].
  564. `OAuth2AuthorizationServerConfigurer` configures the `NimbusJwkSetEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  565. `NimbusJwkSetEndpointFilter` is the `Filter` that returns the https://datatracker.ietf.org/doc/html/rfc7517#section-5[JWK Set].
  566. [NOTE]
  567. The JWK Set endpoint is configured *only* if a `JWKSource<SecurityContext>` `@Bean` is registered.
  568. [[oauth2AuthorizationServer-oidc-provider-configuration-endpoint]]
  569. == OpenID Connect 1.0 Provider Configuration Endpoint
  570. `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].
  571. 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].
  572. `OidcProviderConfigurationEndpointConfigurer` provides the following configuration option:
  573. [source,java]
  574. ----
  575. @Bean
  576. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  577. http
  578. .oauth2AuthorizationServer((authorizationServer) ->
  579. authorizationServer
  580. .oidc(oidc ->
  581. oidc
  582. .providerConfigurationEndpoint(providerConfigurationEndpoint ->
  583. providerConfigurationEndpoint
  584. .providerConfigurationCustomizer(providerConfigurationCustomizer) <1>
  585. )
  586. )
  587. );
  588. return http.build();
  589. }
  590. ----
  591. <1> `providerConfigurationCustomizer()`: The `Consumer` providing access to the `OidcProviderConfiguration.Builder` allowing the ability to customize the claims of the OpenID Provider's configuration.
  592. `OidcProviderConfigurationEndpointConfigurer` configures the `OidcProviderConfigurationEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  593. `OidcProviderConfigurationEndpointFilter` is the `Filter` that returns the https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse[OidcProviderConfiguration response].
  594. [[oauth2AuthorizationServer-oidc-logout-endpoint]]
  595. == OpenID Connect 1.0 Logout Endpoint
  596. `OidcLogoutEndpointConfigurer` provides the ability to customize the https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout[OpenID Connect 1.0 Logout endpoint].
  597. It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for RP-Initiated Logout requests.
  598. `OidcLogoutEndpointConfigurer` provides the following configuration options:
  599. [source,java]
  600. ----
  601. @Bean
  602. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  603. http
  604. .oauth2AuthorizationServer((authorizationServer) ->
  605. authorizationServer
  606. .oidc(oidc ->
  607. oidc
  608. .logoutEndpoint(logoutEndpoint ->
  609. logoutEndpoint
  610. .logoutRequestConverter(logoutRequestConverter) <1>
  611. .logoutRequestConverters(logoutRequestConvertersConsumer) <2>
  612. .authenticationProvider(authenticationProvider) <3>
  613. .authenticationProviders(authenticationProvidersConsumer) <4>
  614. .logoutResponseHandler(logoutResponseHandler) <5>
  615. .errorResponseHandler(errorResponseHandler) <6>
  616. )
  617. )
  618. );
  619. return http.build();
  620. }
  621. ----
  622. <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`.
  623. <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`.
  624. <3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OidcLogoutAuthenticationToken`.
  625. <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`.
  626. <5> `logoutResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OidcLogoutAuthenticationToken` and performing the logout.
  627. <6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the error response.
  628. `OidcLogoutEndpointConfigurer` configures the `OidcLogoutEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  629. `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.
  630. `OidcLogoutEndpointFilter` is configured with the following defaults:
  631. * `*AuthenticationConverter*` -- An `OidcLogoutAuthenticationConverter`.
  632. * `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OidcLogoutAuthenticationProvider`.
  633. * `*AuthenticationSuccessHandler*` -- An `OidcLogoutAuthenticationSuccessHandler`.
  634. * `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
  635. [NOTE]
  636. `OidcLogoutAuthenticationProvider` uses a xref:servlet/oauth2/authorization-server/core-model-components.adoc#oauth2AuthorizationServer-session-registry[`SessionRegistry`] to look up the `SessionInformation` instance associated to the End-User requesting to be logged out.
  637. [TIP]
  638. `OidcClientInitiatedLogoutSuccessHandler` is the corresponding configuration in Spring Security’s OAuth2 Client support for configuring xref:servlet/oauth2/login/advanced.adoc#oauth2login-advanced-oidc-logout[OpenID Connect 1.0 RP-Initiated Logout].
  639. [[oauth2AuthorizationServer-oidc-logout-endpoint-customizing-logout-request-validation]]
  640. === Customizing Logout Request Validation
  641. `OidcLogoutAuthenticationValidator` is the default validator used for validating specific OpenID Connect RP-Initiated Logout Request parameters.
  642. The default implementation validates the `post_logout_redirect_uri` parameter.
  643. If validation fails, an `OAuth2AuthenticationException` is thrown.
  644. `OidcLogoutAuthenticationProvider` provides the ability to override the default logout request validation by supplying a custom authentication validator of type `Consumer<OidcLogoutAuthenticationContext>` to `setAuthenticationValidator()`.
  645. [TIP]
  646. `OidcLogoutAuthenticationContext` holds the `OidcLogoutAuthenticationToken`, which contains the logout request parameters.
  647. [IMPORTANT]
  648. If validation fails, the authentication validator *MUST* throw `OAuth2AuthenticationException`.
  649. The following example shows how to configure `OidcLogoutAuthenticationProvider` with a custom authentication validator:
  650. [source,java]
  651. ----
  652. @Bean
  653. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  654. http
  655. .oauth2AuthorizationServer((authorizationServer) ->
  656. authorizationServer
  657. .oidc(oidc ->
  658. oidc
  659. .logoutEndpoint(logoutEndpoint ->
  660. logoutEndpoint
  661. .authenticationProviders(configureAuthenticationValidator())
  662. )
  663. )
  664. );
  665. return http.build();
  666. }
  667. private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
  668. return (authenticationProviders) ->
  669. authenticationProviders.forEach((authenticationProvider) -> {
  670. if (authenticationProvider instanceof OidcLogoutAuthenticationProvider oidcLogoutAuthenticationProvider) {
  671. Consumer<OidcLogoutAuthenticationContext> authenticationValidator = new CustomPostLogoutRedirectUriValidator();
  672. oidcLogoutAuthenticationProvider.setAuthenticationValidator(authenticationValidator);
  673. }
  674. });
  675. }
  676. static class CustomPostLogoutRedirectUriValidator implements Consumer<OidcLogoutAuthenticationContext> {
  677. @Override
  678. public void accept(OidcLogoutAuthenticationContext authenticationContext) {
  679. OidcLogoutAuthenticationToken oidcLogoutAuthentication =
  680. authenticationContext.getAuthentication();
  681. RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
  682. // TODO
  683. }
  684. }
  685. ----
  686. [[oauth2AuthorizationServer-oidc-user-info-endpoint]]
  687. == OpenID Connect 1.0 UserInfo Endpoint
  688. `OidcUserInfoEndpointConfigurer` provides the ability to customize the https://openid.net/specs/openid-connect-core-1_0.html#UserInfo[OpenID Connect 1.0 UserInfo endpoint].
  689. 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].
  690. `OidcUserInfoEndpointConfigurer` provides the following configuration options:
  691. [source,java]
  692. ----
  693. @Bean
  694. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  695. http
  696. .oauth2AuthorizationServer((authorizationServer) ->
  697. authorizationServer
  698. .oidc(oidc ->
  699. oidc
  700. .userInfoEndpoint(userInfoEndpoint ->
  701. userInfoEndpoint
  702. .userInfoRequestConverter(userInfoRequestConverter) <1>
  703. .userInfoRequestConverters(userInfoRequestConvertersConsumer) <2>
  704. .authenticationProvider(authenticationProvider) <3>
  705. .authenticationProviders(authenticationProvidersConsumer) <4>
  706. .userInfoResponseHandler(userInfoResponseHandler) <5>
  707. .errorResponseHandler(errorResponseHandler) <6>
  708. .userInfoMapper(userInfoMapper) <7>
  709. )
  710. )
  711. );
  712. return http.build();
  713. }
  714. ----
  715. <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`.
  716. <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`.
  717. <3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OidcUserInfoAuthenticationToken`.
  718. <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`.
  719. <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].
  720. <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].
  721. <7> `userInfoMapper()`: The `Function` used to extract claims from `OidcUserInfoAuthenticationContext` to an instance of `OidcUserInfo`.
  722. `OidcUserInfoEndpointConfigurer` configures the `OidcUserInfoEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  723. `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].
  724. `OidcUserInfoEndpointFilter` is configured with the following defaults:
  725. * `*AuthenticationConverter*` -- An internal implementation that obtains the `Authentication` from the `SecurityContext` and creates an `OidcUserInfoAuthenticationToken` with the principal.
  726. * `*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.
  727. * `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OidcUserInfoAuthenticationToken` and returns the `OidcUserInfo` response.
  728. * `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
  729. [TIP]
  730. You can customize the ID Token by providing an xref:servlet/oauth2/authorization-server/core-model-components.adoc#oauth2AuthorizationServer-oauth2-token-customizer[`OAuth2TokenCustomizer<JwtEncodingContext>`] `@Bean`.
  731. 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].
  732. [NOTE]
  733. OAuth2 resource server support is autoconfigured, however, a `JwtDecoder` `@Bean` is *REQUIRED* for the OpenID Connect 1.0 UserInfo endpoint.
  734. [[oauth2AuthorizationServer-oidc-client-registration-endpoint]]
  735. == OpenID Connect 1.0 Client Registration Endpoint
  736. `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].
  737. 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].
  738. `OidcClientRegistrationEndpointConfigurer` provides the following configuration options:
  739. [source,java]
  740. ----
  741. @Bean
  742. public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
  743. http
  744. .oauth2AuthorizationServer((authorizationServer) ->
  745. authorizationServer
  746. .oidc(oidc ->
  747. oidc
  748. .clientRegistrationEndpoint(clientRegistrationEndpoint ->
  749. clientRegistrationEndpoint
  750. .clientRegistrationRequestConverter(clientRegistrationRequestConverter) <1>
  751. .clientRegistrationRequestConverters(clientRegistrationRequestConvertersConsumers) <2>
  752. .authenticationProvider(authenticationProvider) <3>
  753. .authenticationProviders(authenticationProvidersConsumer) <4>
  754. .clientRegistrationResponseHandler(clientRegistrationResponseHandler) <5>
  755. .errorResponseHandler(errorResponseHandler) <6>
  756. )
  757. )
  758. );
  759. return http.build();
  760. }
  761. ----
  762. <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`.
  763. <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`.
  764. <3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OidcClientRegistrationAuthenticationToken`.
  765. <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`.
  766. <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].
  767. <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].
  768. [NOTE]
  769. The OpenID Connect 1.0 Client Registration endpoint is disabled by default because many deployments do not require dynamic client registration.
  770. `OidcClientRegistrationEndpointConfigurer` configures the `OidcClientRegistrationEndpointFilter` and registers it with the OAuth2 authorization server `SecurityFilterChain` `@Bean`.
  771. `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].
  772. [TIP]
  773. `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].
  774. `OidcClientRegistrationEndpointFilter` is configured with the following defaults:
  775. * `*AuthenticationConverter*` -- An `OidcClientRegistrationAuthenticationConverter`.
  776. * `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OidcClientRegistrationAuthenticationProvider` and `OidcClientConfigurationAuthenticationProvider`.
  777. * `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OidcClientRegistrationAuthenticationToken` and returns the `OidcClientRegistration` response.
  778. * `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
  779. 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.
  780. [NOTE]
  781. OAuth2 resource server support is autoconfigured, however, a `JwtDecoder` `@Bean` is *REQUIRED* for the OpenID Connect 1.0 Client Registration endpoint.
  782. [IMPORTANT]
  783. The access token in a Client Registration request *REQUIRES* the OAuth2 scope `client.create`.
  784. [IMPORTANT]
  785. The access token in a Client Read request *REQUIRES* the OAuth2 scope `client.read`.