对于最新的稳定版本,请使用 Spring Security 6.5.3! |
会话管理迁移
以下步骤与如何完成会话管理支持的迁移有关。
需要显式保存 SecurityContextRepository
在 Spring Security 5 中,默认行为是SecurityContext
自动保存到SecurityContextRepository
使用SecurityContextPersistenceFilter
.
保存必须在HttpServletResponse
正在承诺和就在之前SecurityContextPersistenceFilter
.
不幸的是,自动持久化SecurityContext
在请求完成之前(即在提交HttpServletResponse
).
跟踪状态以确定是否需要保存也很复杂,这会导致对SecurityContextRepository
(即HttpSession
)有时。
在 Spring Security 6 中,默认行为是SecurityContextHolderFilter
只会读取SecurityContext
从SecurityContextRepository
并将其填充在SecurityContextHolder
.
用户现在必须显式保存SecurityContext
使用SecurityContextRepository
如果他们想要SecurityContext
在请求之间保留。
这消除了歧义并通过只需要写入SecurityContextRepository
(即HttpSession
)在必要时。
清除上下文时(例如在注销期间)也需要保存上下文。请参阅本节以了解更多信息。 |
如果您显式选择加入 Spring Security 6 的新默认值,则可以删除以下配置以接受 Spring Security 6 默认值。
-
Java
-
Kotlin
-
XML
public SecurityFilterChain filterChain(HttpSecurity http) {
http
// ...
.securityContext((securityContext) -> securityContext
.requireExplicitSave(true)
);
return http.build();
}
@Bean
open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
http {
securityContext {
requireExplicitSave = true
}
}
return http.build()
}
<http security-context-explicit-save="true">
<!-- ... -->
</http>
使用配置时,重要的是,任何将SecurityContextHolder
使用SecurityContext
还保存了SecurityContext
到SecurityContextRepository
如果它应该在请求之间持久化。
例如,以下代码:
SecurityContextHolder
跟SecurityContextPersistenceFilter
-
Java
-
Kotlin
SecurityContextHolder.setContext(securityContext);
SecurityContextHolder.setContext(securityContext)
应该替换为
SecurityContextHolder
跟SecurityContextHolderFilter
-
Java
-
Kotlin
SecurityContextHolder.setContext(securityContext);
securityContextRepository.saveContext(securityContext, httpServletRequest, httpServletResponse);
SecurityContextHolder.setContext(securityContext)
securityContextRepository.saveContext(securityContext, httpServletRequest, httpServletResponse)
多个 SecurityContextRepository
在 Spring Security 5 中,默认的SecurityContextRepository
是HttpSessionSecurityContextRepository
.
在 Spring Security 6 中,默认的SecurityContextRepository
是DelegatingSecurityContextRepository
.
如果您配置了SecurityContextRepository
仅出于更新到 6.0 的目的,您可以将其完全删除。
优化查询RequestCache
在 Spring Security 5 中,默认行为是在每个请求时查询保存的请求。
这意味着在典型设置中,为了使用RequestCache
这HttpSession
在每个请求时都会被查询。
在 Spring Security 6 中,默认值是RequestCache
只有在 HTTP 参数continue
被定义。
这允许 Spring Security 避免不必要地读取HttpSession
使用RequestCache
.
在 Spring Security 5 中,默认值是使用HttpSessionRequestCache
将在每个请求中查询缓存的请求。
如果您没有覆盖默认值(即使用NullRequestCache
),则可以使用以下配置在 Spring Security 5.8 中显式选择加入 Spring Security 6 行为:
RequestCache
仅在以下情况下检查已保存的请求continue
参数存在-
Java
-
Kotlin
-
XML
@Bean
DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
HttpSessionRequestCache requestCache = new HttpSessionRequestCache();
requestCache.setMatchingRequestParameterName("continue");
http
// ...
.requestCache((cache) -> cache
.requestCache(requestCache)
);
return http.build();
}
@Bean
open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
val httpRequestCache = HttpSessionRequestCache()
httpRequestCache.setMatchingRequestParameterName("continue")
http {
requestCache {
requestCache = httpRequestCache
}
}
return http.build()
}
<http auto-config="true">
<!-- ... -->
<request-cache ref="requestCache"/>
</http>
<b:bean id="requestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache"
p:matchingRequestParameterName="continue"/>