protocol-endpoints.adoc 69 KB

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