Session Management 迁移
本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springboot.io - Spring Boot中文社区 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。 |
下面的步骤涉及到如何完成迁移会话管理支持。
要求明确保存 SecurityContextRepository
在Spring Security 5中,默认行为是使用 SecurityContextPersistenceFilter
将 SecurityContext
自动保存到 SecurityContextRepository
中。保存必须在 HttpServletResponse
被提交之前和 SecurityContextPersistenceFilter
之前进行。不幸的是,当 SecurityContext
的自动持久化在请求完成之前(即在提交 HttpServletResponse
之前)完成时,会让用户感到惊讶。跟踪状态以确定是否需要保存也很复杂,有时会导致对 SecurityContextRepository
(即 HttpSession
)进行不必要的写入。
在 Spring Security 6 中,默认行为是 SecurityContextHolderFilter
只从 SecurityContextRepository
读取 SecurityContext
并将其填充到 SecurityContextHolder
中。现在,如果用户希望 SecurityContext
在不同请求之间持续存在,他们必须明确地将 SecurityContext
与 SecurityContextRepository
一起保存。这消除了歧义,并通过仅在必要时要求写入 SecurityContextRepository
(即 HttpSession
)来提高性能。
如果你明确选择加入Spring Security 6的新默认值,可以删除以下配置以接受Spring Security 6的默认值。
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
with SecurityContextPersistenceFilter
SecurityContextHolder.setContext(securityContext);
SecurityContextHolder.setContext(securityContext)
should be replaced with
SecurityContextHolder
with SecurityContextHolderFilter
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,你可以完全删除它。
== SecurityContextRepository 的弃用
对于这种废弃,没有进一步的迁移步骤。
== 优化 RequestCache
查询
在Spring Security 5中,默认行为是在每个请求中查询 已保存的请求。这意味着在一个典型的设置中,为了使用 RequestCache
,每次请求都要查询 HttpSession
。
在Spring Security 6中,默认情况下,只有在定义了 HTTP 参数 continue
的情况下, RequestCache
才会被查询到缓存的请求。这使得 Spring Security 可以避免不必要地用 RequestCache
读取 HttpSession
。
在Spring Security 5中,默认是使用 HttpSessionRequestCache
,它将在每个请求中被查询到一个缓存的请求。如果你没有覆盖默认值(即使用 NullRequestCache
),那么可以使用以下配置在Spring Security 5.8中明确选择Spring Security 6的行为。
@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"/>