Spring Security配置Quartz Manager的一次异常
问题描述:
Spring Security的配置如下,期望对/quartz-manager-ui/路径下的所有资源进行httpBasic和formLogin认证
@Bean
@Order(1)
public SecurityFilterChain formSecurityFilterChain(HttpSecurity http) {
try {
return http
.csrf(AbstractHttpConfigurer::disable)
.cors(AbstractHttpConfigurer::disable)
//.securityMatcher("/druid/**", "/login")
.securityMatchers((config) -> config
.requestMatchers(
AntPathRequestMatcher.antMatcher("/druid/**"),
AntPathRequestMatcher.antMatcher("/login"),
AntPathRequestMatcher.antMatcher("/doc.html/**"),
AntPathRequestMatcher.antMatcher("/v3/api-docs/**"),
AntPathRequestMatcher.antMatcher("/webjars/**"),
AntPathRequestMatcher.antMatcher("/swagger*/**"),
AntPathRequestMatcher.antMatcher("/default-ui.css"),
AntPathRequestMatcher.antMatcher("/quartz-manager-ui/**")
))
.authorizeHttpRequests((config) -> {
config.anyRequest().authenticated();
})
.httpBasic((configurer) -> {})
.formLogin(Customizer.withDefaults())
.build();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
以上配置的实际效果:
在第一次登录时(即cookie中的JSESSION没有任何信息时),可以正常登录,但是进入后页面出现404:

之后所有的请求都会出现403 code,这是什么原因呢?
原因:
- 这个页面上有部分接口非
/quartz-manager-ui/开头,例如:/quartz-manager/auth/whoami - 项目中还配置了另外一个SecurityFilterChain,
/quartz-manager/auth/whoami接口没有走上面配置的SecurityFilterChain,从而导致该接口认证失败,且返回了认证失败信息:
![image]()
- 在Spring Security的流程中,认证失败会情况SecurityContext中的信息,也即会清除第一次表单登录后的用户信息,所以导致了之后的接口都出现了403错误,代码如下:
org.springframework.security.web.access.ExceptionTranslationFilter#sendStartAuthenticationprotected void sendStartAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, AuthenticationException reason) throws ServletException, IOException { // SEC-112: Clear the SecurityContextHolder's Authentication, as the // existing Authentication is no longer considered valid SecurityContext context = this.securityContextHolderStrategy.createEmptyContext(); //情况登录信息 this.securityContextHolderStrategy.setContext(context); this.requestCache.saveRequest(request, response); this.authenticationEntryPoint.commence(request, response, reason); }
解决方案:
在SecurityFilterChain添加/quartz-manager/**路径匹配
@Bean
@Order(1)
public SecurityFilterChain formSecurityFilterChain(HttpSecurity http) {
try {
return http
.csrf(AbstractHttpConfigurer::disable)
.cors(AbstractHttpConfigurer::disable)
//.securityMatcher("/druid/**", "/login")
.securityMatchers((config) -> config
.requestMatchers(
AntPathRequestMatcher.antMatcher("/druid/**"),
AntPathRequestMatcher.antMatcher("/login"),
AntPathRequestMatcher.antMatcher("/doc.html/**"),
AntPathRequestMatcher.antMatcher("/v3/api-docs/**"),
AntPathRequestMatcher.antMatcher("/webjars/**"),
AntPathRequestMatcher.antMatcher("/swagger*/**"),
AntPathRequestMatcher.antMatcher("/default-ui.css"),
AntPathRequestMatcher.antMatcher("/quartz-manager-ui/**"),
AntPathRequestMatcher.antMatcher("/quartz-manager/**")
))
.authorizeHttpRequests((config) -> {
config.anyRequest().authenticated();
})
.httpBasic((configurer) -> {})
.formLogin(Customizer.withDefaults())
.build();
} catch (Exception e) {
throw new RuntimeException(e);
}
}


浙公网安备 33010602011771号