为何安全过滤器链无UsernamePasswordAuthenticationFilter及链序疑问
关于Spring Security过滤器链的两个疑问
背景配置代码
http .cors().configurationSource(new CorsConfigurationSource() { @Override public CorsConfiguration getCorsConfiguration(HttpServletRequest request) { CorsConfiguration config = new CorsConfiguration(); //todo: this should be set as environment variable config.setAllowedOrigins(Collections.singletonList("http://localhost")); config.setAllowedMethods(Collections.singletonList("*")); config.setAllowCredentials(true); config.setAllowedHeaders(Collections.singletonList("*")); config.setExposedHeaders(List.of("Authorization")); //todo: what does this mean? config.setMaxAge(3600L); return config; } }) .and().csrf().disable()//todo: set csrf() in prod: ignoringRequestMatch .authorizeHttpRequests() .requestMatchers("/api/v1/auth/**").permitAll() //authorized all the target here .anyRequest().authenticated() .and().sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // do not store any state .and().authenticationProvider(authenticationProvider) .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
过滤器链日志
开启logging.level.org.springframework.security.web.FilterChainProxy=DEBUG后,输出日志如下:
Security filter chain: [ DisableEncodeUrlFilter WebAsyncManagerIntegrationFilter SecurityContextHolderFilter HeaderWriterFilter CorsFilter LogoutFilter JwtAuthenticationFilter RequestCacheAwareFilter SecurityContextHolderAwareRequestFilter AnonymousAuthenticationFilter SessionManagementFilter ExceptionTranslationFilter AuthorizationFilter ]
疑问
- 为何
UsernamePasswordAuthenticationFilter.class不在过滤器链中? - 日志打印的过滤器链顺序是否正确?若不正确,何处可获取正确顺序?
解答
1. UsernamePasswordAuthenticationFilter不在链中的原因
UsernamePasswordAuthenticationFilter是Spring Security为表单登录场景设计的过滤器,只有当你在配置中显式启用表单登录(比如调用.formLogin())时,它才会被自动加入过滤器链。
你的项目配置了SessionCreationPolicy.STATELESS(无状态会话),且采用JWT认证方案,完全不需要依赖表单登录流程,所以Spring Security不会自动添加这个过滤器。你用addFilterBefore指定它作为JWT过滤器的参照位置,只是利用它在默认过滤器链中的预设位置来确定JWT过滤器的插入点——即便它本身不在当前链中,Spring Security依然能识别这个位置并正确插入你的自定义JWT过滤器。
2. 过滤器链顺序正确性及获取方式
当前日志中的过滤器链顺序是正确的,完全适配无状态JWT认证的场景:
CorsFilter排在认证类过滤器之前,确保跨域请求先被处理JwtAuthenticationFilter在AnonymousAuthenticationFilter之前,保证JWT认证优先执行,避免匿名认证提前生效- 后续的
SessionManagementFilter、ExceptionTranslationFilter、AuthorizationFilter也都处于标准的执行位置
如果需要确认官方标准的过滤器链顺序,可以通过以下方式:
- 查看Spring Security官方文档中关于过滤器链的章节
- 在本地项目中调试
FilterChainProxy类,查看默认过滤器的排序逻辑 - 自定义过滤器时,使用
addFilterBefore/addFilterAfter方法指定参照过滤器,Spring Security会按照默认的过滤器顺序规则自动放置你的自定义过滤器
内容的提问来源于stack exchange,提问作者Alex Teng
相关产品推荐
相关产品推荐

