migration.adoc 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. [[migration]]
  2. = Migrating to 6.0
  3. The Spring Security team has prepared the 5.8 release to simplify upgrading to Spring Security 6.0.
  4. Use 5.8 and the steps below to minimize changes when
  5. ifdef::spring-security-version[]
  6. xref:6.0.0@migration.adoc[updating to 6.0]
  7. endif::[]
  8. ifndef::spring-security-version[]
  9. updating to 6.0
  10. endif::[]
  11. .
  12. == Servlet
  13. === Explicit Save SecurityContextRepository
  14. In Spring Security 5, the default behavior is for the xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontext[`SecurityContext`] to automatically be saved to the xref:servlet/authentication/persistence.adoc#securitycontextrepository[`SecurityContextRepository`] using the xref:servlet/authentication/persistence.adoc#securitycontextpersistencefilter[`SecurityContextPersistenceFilter`].
  15. Saving must be done just prior to the `HttpServletResponse` being committed and just before `SecurityContextPersistenceFilter`.
  16. Unfortunately, automatic persistence of the `SecurityContext` can surprise users when it is done prior to the request completing (i.e. just prior to committing the `HttpServletResponse`).
  17. It also is complex to keep track of the state to determine if a save is necessary causing unnecessary writes to the `SecurityContextRepository` (i.e. `HttpSession`) at times.
  18. In Spring Security 6, the default behavior is that the xref:servlet/authentication/persistence.adoc#securitycontextholderfilter[`SecurityContextHolderFilter`] will only read the `SecurityContext` from `SecurityContextRepository` and populate it in the `SecurityContextHolder`.
  19. Users now must explicitly save the `SecurityContext` with the `SecurityContextRepository` if they want the `SecurityContext` to persist between requests.
  20. This removes ambiguity and improves performance by only requiring writing to the `SecurityContextRepository` (i.e. `HttpSession`) when it is necessary.
  21. To opt into the new Spring Security 6 default, the following configuration can be used.
  22. include::partial$servlet/architecture/security-context-explicit.adoc[]
  23. [[requestcache-query-optimization]]
  24. === Optimize Querying of `RequestCache`
  25. In Spring Security 5, the default behavior is to query the xref:servlet/architecture.adoc#savedrequests[saved request] on every request.
  26. This means that in a typical setup, that in order to use the xref:servlet/architecture.adoc#requestcache[`RequestCache`] the `HttpSession` is queried on every request.
  27. In Spring Security 6, the default is that `RequestCache` will only be queried for a cached request if the HTTP parameter `continue` is defined.
  28. This allows Spring Security to avoid unnecessarily reading the `HttpSession` with the `RequestCache`.
  29. In Spring Security 5 the default is to use `HttpSessionRequestCache` which will be queried for a cached request on every request.
  30. If you are not overriding the defaults (i.e. using `NullRequestCache`), then the following configuration can be used to explicitly opt into the Spring Security 6 behavior in Spring Security 5.8:
  31. include::partial$servlet/architecture/request-cache-continue.adoc[]
  32. === Use `AuthorizationManager` for Method Security
  33. xref:servlet/authorization/method-security.adoc[Method Security] has been xref:servlet/authorization/method-security.adoc#jc-enable-method-security[simplified] through {security-api-url}org/springframework/security/authorization/AuthorizationManager.html[the `AuthorizationManager` API] and direct use of Spring AOP.
  34. '''
  35. [[servlet-replace-globalmethodsecurity-with-methodsecurity]]
  36. ==== Replace xref:servlet/authorization/method-security.adoc#jc-enable-global-method-security[global method security] with xref:servlet/authorization/method-security.adoc#jc-enable-method-security[method security]
  37. {security-api-url}org/springframework/security/config/annotation/method/configuration/EnableGlobalMethodSecurity.html[`@EnableGlobalMethodSecurity`] and xref:servlet/appendix/namespace/method-security.adoc#nsa-global-method-security[`<global-method-security>`] are deprecated in favor of {security-api-url}org/springframework/security/config/annotation/method/configuration/EnableMethodSecurity.html[`@EnableMethodSecurity`] and xref:servlet/appendix/namespace/method-security.adoc#nsa-method-security[`<method-security>`], respectively.
  38. The new annotation and XML element activate Spring's xref:servlet/authorization/method-security.adoc#jc-enable-method-security[pre-post annotations] by default and use `AuthorizationManager` internally.
  39. This means that the following two listings are functionally equivalent:
  40. ====
  41. .Java
  42. [source,java,role="primary"]
  43. ----
  44. @EnableGlobalMethodSecurity(prePostEnabled = true)
  45. ----
  46. .Kotlin
  47. [source,kotlin,role="secondary"]
  48. ----
  49. @EnableGlobalMethodSecurity(prePostEnabled = true)
  50. ----
  51. .Xml
  52. [source,xml,role="secondary"]
  53. ----
  54. <global-method-security pre-post-enabled="true"/>
  55. ----
  56. ====
  57. and:
  58. ====
  59. .Java
  60. [source,java,role="primary"]
  61. ----
  62. @EnableMethodSecurity
  63. ----
  64. .Kotlin
  65. [source,kotlin,role="secondary"]
  66. ----
  67. @EnableMethodSecurity
  68. ----
  69. .Xml
  70. [source,xml,role="secondary"]
  71. ----
  72. <method-security/>
  73. ----
  74. ====
  75. For applications not using the pre-post annotations, make sure to turn it off to avoid activating unwanted behavior.
  76. For example, a listing like:
  77. ====
  78. .Java
  79. [source,java,role="primary"]
  80. ----
  81. @EnableGlobalMethodSecurity(securedEnabled = true)
  82. ----
  83. .Kotlin
  84. [source,kotlin,role="secondary"]
  85. ----
  86. @EnableGlobalMethodSecurity(securedEnabled = true)
  87. ----
  88. .Xml
  89. [source,xml,role="secondary"]
  90. ----
  91. <global-method-security secured-enabled="true"/>
  92. ----
  93. ====
  94. should change to:
  95. ====
  96. .Java
  97. [source,java,role="primary"]
  98. ----
  99. @EnableMethodSecurity(securedEnabled = true, prePostEnabled = false)
  100. ----
  101. .Kotlin
  102. [source,kotlin,role="secondary"]
  103. ----
  104. @EnableMethodSecurity(securedEnabled = true, prePostEnabled = false)
  105. ----
  106. .Xml
  107. [source,xml,role="secondary"]
  108. ----
  109. <method-security secured-enabled="true" pre-post-enabled="false"/>
  110. ----
  111. ====
  112. '''
  113. [[servlet-replace-permissionevaluator-bean-with-methodsecurityexpression-handler]]
  114. ==== Publish a `MethodSecurityExpressionHandler` instead of a `PermissionEvaluator`
  115. `@EnableMethodSecurity` does not pick up a `PermissionEvaluator`.
  116. This helps keep its API simple.
  117. If you have a custom {security-api-url}org/springframework/security/access/PermissionEvaluator.html[`PermissionEvaluator`] `@Bean`, please change it from:
  118. ====
  119. .Java
  120. [source,java,role="primary"]
  121. ----
  122. @Bean
  123. static PermissionEvaluator permissionEvaluator() {
  124. // ... your evaluator
  125. }
  126. ----
  127. .Kotlin
  128. [source,kotlin,role="secondary"]
  129. ----
  130. companion object {
  131. @Bean
  132. fun permissionEvaluator(): PermissionEvaluator {
  133. // ... your evaluator
  134. }
  135. }
  136. ----
  137. ====
  138. to:
  139. ====
  140. .Java
  141. [source,java,role="primary"]
  142. ----
  143. @Bean
  144. static MethodSecurityExpressionHandler expressionHandler() {
  145. var expressionHandler = new DefaultMethodSecurityExpressionHandler();
  146. expressionHandler.setPermissionEvaluator(myPermissionEvaluator);
  147. return expressionHandler;
  148. }
  149. ----
  150. .Kotlin
  151. [source,kotlin,role="secondary"]
  152. ----
  153. companion object {
  154. @Bean
  155. fun expressionHandler(): MethodSecurityExpressionHandler {
  156. val expressionHandler = DefaultMethodSecurityExpressionHandler
  157. expressionHandler.setPermissionEvaluator(myPermissionEvaluator)
  158. return expressionHandler
  159. }
  160. }
  161. ----
  162. ====
  163. '''
  164. [[servlet-check-for-annotationconfigurationexceptions]]
  165. ==== Check for ``AnnotationConfigurationException``s
  166. `@EnableMethodSecurity` and `<method-security>` activate stricter enforcement of Spring Security's non-repeatable or otherwise incompatible annotations.
  167. If after moving to either you see ``AnnotationConfigurationException``s in your logs, follow the instructions in the exception message to clean up your application's method security annotation usage.
  168. == Reactive
  169. === Use `AuthorizationManager` for Method Security
  170. 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.
  171. '''
  172. [[reactive-change-to-useauthorizationmanager]]
  173. ==== Change `useAuthorizationManager` to `true`
  174. 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.
  175. To opt in, change `useAuthorizationManager` to `true` like so:
  176. ====
  177. .Java
  178. [source,java,role="primary"]
  179. ----
  180. @EnableReactiveMethodSecurity
  181. ----
  182. .Kotlin
  183. [source,kotlin,role="secondary"]
  184. ----
  185. @EnableReactiveMethodSecurity
  186. ----
  187. ====
  188. changes to:
  189. ====
  190. .Java
  191. [source,java,role="primary"]
  192. ----
  193. @EnableReactiveMethodSecurity(useAuthorizationManager = true)
  194. ----
  195. .Kotlin
  196. [source,kotlin,role="secondary"]
  197. ----
  198. @EnableReactiveMethodSecurity(useAuthorizationManager = true)
  199. ----
  200. ====
  201. [NOTE]
  202. =====
  203. In 6.0, `useAuthorizationManager` defaults to `true`.
  204. =====
  205. '''
  206. [[reactive-check-for-annotationconfigurationexceptions]]
  207. ==== Check for ``AnnotationConfigurationException``s
  208. `useAuthorizationManager` activates stricter enforcement of Spring Security's non-repeatable or otherwise incompatible annotations.
  209. 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.