spring security 6.0.8(boot 3.0.13)自定义 filter 踩坑-已解决
spring boot 3.0.13(3.1.10)
spring security 6.0.8(6.1.8)
--
官方文档:
https://docs.spring.io/spring-security/reference/index.html
写文时最新为 6.2.3 。
说明,先是用 spring boot 3.1.10 测试,失败,降低到 3.0.13 仍然失败。
开发
建立了 AppLoginFilter,实现了 attemptAuthentication 方法。
在 AppSecurityConfig 配置了:
@Configuration @Bean appLoginFilter.setAuthenticationSuccessHandler(new AppLoginSuccessHandler()); appLoginFilter.setAuthenticationManager(authenticationManager); // todo more return appLoginFilter; @Bean throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated() ) .csrf(csrf -> csrf.disable()) .cors(cors -> cors.disable()) .addFilterAt(appLoginFilter, UsernamePasswordAuthenticationFilter.class) .formLogin(formlogin -> formlogin.disable()) .httpBasic(httpbasic -> httpbasic.disable()) ;
return http.build();
}
// more
}
|
登录接口:/app/login。
另外开发了测试接口:/test/getAppName。
发现问题
测试时,/app/login 正常调用,也有 Set-Cookie 响应头。
可是,使用 Set-Cookie 的 Cookie 访问 /test/getAppName 接口时,被拒绝了。
C:\Users\Mi>curl -v -X POST http://localhost:29001/app/login -H "Content-Type: application/json" -d "{\"username\": \"user\", \"password\":\"111\"}" C:\Users\Mi> |
后台出现一条警告日志:
WARN 5256 --- [io-29001-exec-3] o.s.w.s.h.HandlerMappingIntrospector : Cache miss for REQUEST dispatch to '/test/getAppName' (previous null). Performing MatchableHandlerMapping lookup. This is logged once only at WARN level, and every time at TRACE. |
忽略该信息。
解决方案
给 自定义 filter 设置 SecurityContextRepository 为 HttpSessionSecurityContextRepository 即可。
SecurityContextRepository repo = new HttpSessionSecurityContextRepository(); appLoginFilter.setSecurityContextRepository(repo); |
添加后,再次测试,成功。
说明,该方法设置了 AbstractAuthenticationProcessingFilter 的 securityContextRepository 属性,其默认值为:
private SecurityContextRepository securityContextRepository = new RequestAttributeSecurityContextRepository(); |
调试过程
在 自定义的 AppLoginFilter 的 父类 AbstractAuthenticationProcessingFilter#325 中有一个 successfulAuthentication 函数,其中会调用:
this.securityContextHolderStrategy.setContext(context); |
调试发现,这里的 this.securityContextHolderStrategy 值为 RequestAttributeSecurityContextRepository 实例,而不是 HttpSessionSecurityContextRepository 实例。
而在 SecurityContextHolderFilter 中,其值为 DelegatingSecurityContextRepository 实例——包含两个 SecurityContextRepository,其中一个是 HttpSessionSecurityContextRepository 。
官方文档:SecurityContextRepository
Persisting Authentication # SecurityContextRepository
https://docs.spring.io/spring-security/reference/servlet/authentication/persistence.html
The HttpSessionSecurityContextRepository associates the SecurityContext to the HttpSession.
The RequestAttributeSecurityContextRepository saves the SecurityContext as a request attribute to make sure the SecurityContext is available for a single request that occurs across dispatch types that may clear out the SecurityContext.
---END---
ben发布于博客园
本文链接:
https://www.cnblogs.com/luo630/p/18111645
ben发布于博客园
ben发布于博客园