reactive.adoc 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. = Reactive Migrations
  2. If you have already performed the xref:migration/index.adoc[initial migration steps] for your Reactive application, you're now ready to perform steps specific to Reactive applications.
  3. == Use `AuthorizationManager` for Method Security
  4. xref:reactive/authorization/method.adoc[Method Security] has been xref:reactive/authorization/method.adoc#jc-enable-reactive-method-security-authorization-manager[improved] through {security-api-url}org/springframework/security/authorization/AuthorizationManager.html[the `AuthorizationManager` API] and direct use of Spring AOP.
  5. Should you run into trouble with making these changes, you can follow the
  6. <<reactive-authorizationmanager-methods-opt-out,opt out steps>> at the end of this section.
  7. In Spring Security 5.8, `useAuthorizationManager` was added to {security-api-url}org/springframework/security/config/annotation/method/configuration/EnableReactiveMethodSecurity.html[`@EnableReactiveMethodSecurity`] to allow applications to opt in to ``AuthorizationManager``'s features.
  8. [[reactive-change-to-useauthorizationmanager]]
  9. === Change `useAuthorizationManager` to `true`
  10. To opt in, change `useAuthorizationManager` to `true` like so:
  11. ====
  12. .Java
  13. [source,java,role="primary"]
  14. ----
  15. @EnableReactiveMethodSecurity
  16. ----
  17. .Kotlin
  18. [source,kotlin,role="secondary"]
  19. ----
  20. @EnableReactiveMethodSecurity
  21. ----
  22. ====
  23. changes to:
  24. ====
  25. .Java
  26. [source,java,role="primary"]
  27. ----
  28. @EnableReactiveMethodSecurity(useAuthorizationManager = true)
  29. ----
  30. .Kotlin
  31. [source,kotlin,role="secondary"]
  32. ----
  33. @EnableReactiveMethodSecurity(useAuthorizationManager = true)
  34. ----
  35. ====
  36. [[reactive-check-for-annotationconfigurationexceptions]]
  37. === Check for ``AnnotationConfigurationException``s
  38. `useAuthorizationManager` activates stricter enforcement of Spring Security's non-repeatable or otherwise incompatible annotations.
  39. If after turning on `useAuthorizationManager` you see ``AnnotationConfigurationException``s in your logs, follow the instructions in the exception message to clean up your application's method security annotation usage.
  40. [[reactive-authorizationmanager-methods-opt-out]]
  41. === Opt-out Steps
  42. If you ran into trouble with `AuthorizationManager` for reactive method security, you can opt out by changing:
  43. ====
  44. .Java
  45. [source,java,role="primary"]
  46. ----
  47. @EnableReactiveMethodSecurity
  48. ----
  49. .Kotlin
  50. [source,kotlin,role="secondary"]
  51. ----
  52. @EnableReactiveMethodSecurity
  53. ----
  54. ====
  55. to:
  56. ====
  57. .Java
  58. [source,java,role="primary"]
  59. ----
  60. @EnableReactiveMethodSecurity(useAuthorizationManager = false)
  61. ----
  62. .Kotlin
  63. [source,kotlin,role="secondary"]
  64. ----
  65. @EnableReactiveMethodSecurity(useAuthorizationManager = false)
  66. ----
  67. ====
  68. == Propagate ``AuthenticationServiceException``s
  69. {security-api-url}org/springframework/security/web/server/Webauthentication/AuthenticationWebFilter.html[`AuthenticationFilter`] propagates {security-api-url}org/springframework/security/authentication/AuthenticationServiceException.html[``AuthenticationServiceException``]s to the {security-api-url}org/springframework/security/web/server/ServerAuthenticationEntryPoint.html[`ServerAuthenticationEntryPoint`].
  70. Because ``AuthenticationServiceException``s represent a server-side error instead of a client-side error, in 6.0, this changes to propagate them to the container.
  71. === Configure `ServerAuthenticationFailureHandler` to rethrow ``AuthenticationServiceException``s
  72. To prepare for the 6.0 default, `httpBasic` and `oauth2ResourceServer` should be configured to rethrow ``AuthenticationServiceException``s.
  73. For each, construct the appropriate authentication entry point for `httpBasic` and for `oauth2ResourceServer`:
  74. ====
  75. .Java
  76. [source,java,role="primary"]
  77. ----
  78. ServerAuthenticationEntryPoint bearerEntryPoint = new BearerTokenServerAuthenticationEntryPoint();
  79. ServerAuthenticationEntryPoint basicEntryPoint = new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED);
  80. ----
  81. .Kotlin
  82. [source,kotlin,role="secondary"]
  83. ----
  84. val bearerEntryPoint: ServerAuthenticationEntryPoint = BearerTokenServerAuthenticationEntryPoint()
  85. val basicEntryPoint: ServerAuthenticationEntryPoint = HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED)
  86. ----
  87. ====
  88. [NOTE]
  89. ====
  90. If you use a custom `AuthenticationEntryPoint` for either or both mechanisms, use that one instead for the remaining steps.
  91. ====
  92. Then, construct and configure a `ServerAuthenticationEntryPointFailureHandler` for each one:
  93. ====
  94. .Java
  95. [source,java,role="primary"]
  96. ----
  97. AuthenticationFailureHandler bearerFailureHandler = new ServerAuthenticationEntryPointFailureHandler(bearerEntryPoint);
  98. bearerFailureHandler.setRethrowAuthenticationServiceException(true);
  99. AuthenticationFailureHandler basicFailureHandler = new ServerAuthenticationEntryPointFailureHandler(basicEntryPoint);
  100. basicFailureHandler.setRethrowAuthenticationServiceException(true)
  101. ----
  102. .Kotlin
  103. [source,kotlin,role="secondary"]
  104. ----
  105. val bearerFailureHandler: AuthenticationFailureHandler = ServerAuthenticationEntryPointFailureHandler(bearerEntryPoint)
  106. bearerFailureHandler.setRethrowAuthenticationServiceException(true)
  107. val basicFailureHandler: AuthenticationFailureHandler = ServerAuthenticationEntryPointFailureHandler(basicEntryPoint)
  108. basicFailureHandler.setRethrowAuthenticationServiceException(true)
  109. ----
  110. ====
  111. Finally, wire each authentication failure handler into the DSL, like so:
  112. ====
  113. .Java
  114. [source,java,role="primary"]
  115. ----
  116. http
  117. .httpBasic((basic) -> basic.authenticationFailureHandler(basicFailureHandler))
  118. .oauth2ResourceServer((oauth2) -> oauth2.authenticationFailureHandler(bearerFailureHandler))
  119. ----
  120. .Kotlin
  121. [source,kotlin,role="secondary"]
  122. ----
  123. http {
  124. httpBasic {
  125. authenticationFailureHandler = basicFailureHandler
  126. }
  127. oauth2ResourceServer {
  128. authenticationFailureHandler = bearerFailureHandler
  129. }
  130. }
  131. ----
  132. ====
  133. [[reactive-authenticationfailurehandler-opt-out]]
  134. === Opt-out Steps
  135. To opt-out of the 6.0 defaults and instead continue to pass `AuthenticationServiceException` on to ``ServerAuthenticationEntryPoint``s, you can follow the same steps as above, except set `rethrowAuthenticationServiceException` to false.
  136. == Address OAuth2 Client Deprecations
  137. === `ServerOAuth2AuthorizedClientExchangeFilterFunction`
  138. The method `setAccessTokenExpiresSkew(...)` can be replaced with one of:
  139. * `ClientCredentialsReactiveOAuth2AuthorizedClientProvider#setClockSkew(...)`
  140. * `RefreshTokenReactiveOAuth2AuthorizedClientProvider#setClockSkew(...)`
  141. * `JwtBearerReactiveOAuth2AuthorizedClientProvider#setClockSkew(...)`
  142. The method `setClientCredentialsTokenResponseClient(...)` can be replaced with the constructor `ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager)`.
  143. [NOTE]
  144. ====
  145. See xref:reactive/oauth2/client/authorization-grants.adoc#oauth2Client-client-creds-grant[Client Credentials] for more information.
  146. ====
  147. === `WebSessionOAuth2ServerAuthorizationRequestRepository`
  148. The method `setAllowMultipleAuthorizationRequests(...)` has no direct replacement.
  149. === `UnAuthenticatedServerOAuth2AuthorizedClientRepository`
  150. The class `UnAuthenticatedServerOAuth2AuthorizedClientRepository` has no direct replacement. Usage of the class can be replaced with `AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager`.