Spring Security中anyRequest().authenticated()未按预期生效问题
嘿,我来帮你搞定这个问题!首先你对http.anyRequest().authenticated()的理解完全正确——它就是要求所有进入应用的请求都必须经过认证,未认证的请求应该被拦截并返回401(如果没配置表单登录的话)。但你的应用居然允许未认证请求直接通过,大概率是这几个常见坑导致的:
1. 配置类的@Order优先级搞混了
你给配置类加了@Order(1),如果项目里还有其他Spring Security配置类,优先级更高的(Order值越小越优先)可能直接覆盖了你的规则,或者这个配置类根本没被Spring正确加载,甚至其他配置类写了全局放行的规则(比如anyRequest().permitAll()),那你的配置就被忽略了。
举个例子,如果有另一个配置类标了@Order(0),里面写了http.authorizeRequests().anyRequest().permitAll(),那这个会先生效,你的认证规则自然就不起作用了。
2. configure(HttpSecurity)方法里的链式调用出错了
你只贴了部分代码,会不会是你在配置的时候不小心加了permitAll()的规则,或者链式调用的顺序错了?比如:
@Override protected void configure(HttpSecurity http) throws Exception { http .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class) .authorizeRequests() // 要是这里有类似 .antMatchers("/**").permitAll() 的代码,直接就把后面的authenticated()覆盖了 .anyRequest().authenticated(); }
一定要确保在anyRequest().authenticated()之前,没有写全局放行的规则。
3. 自定义的AuthenticationTokenFilter没干活
你注入了AuthenticationTokenFilter,如果这个过滤器没正确处理认证逻辑,或者没把认证信息存入SecurityContext,那Spring Security就会认为请求没认证,但如果过滤器直接把请求放行了,后续的认证规则也不会生效。
你得检查下这个过滤器的实现:
- 是不是在
doFilterInternal方法里,当token有效时,创建了Authentication对象,并且调用了SecurityContextHolder.getContext().setAuthentication(auth)? - 如果token无效,是不是没抛出异常或者没触发认证失败的逻辑,直接让请求溜过去了?
4. Spring Security版本的兼容性问题
如果你用的是Spring Security 5.7及以上的版本,WebSecurityConfigurerAdapter已经被标记为过时了,官方推荐用基于组件的配置方式。要是你还在继承这个类,可能和新版本的自动配置冲突,导致你的自定义配置不生效。
这种情况的话,改成新的配置方式试试:
@Configuration @Order(1) public class SecurityConfiguration { @Autowired private AuthenticationTokenFilter authenticationTokenFilter; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class) .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() ); return http.build(); } }
5. 静态资源被默认放行了
Spring Security默认会放行一些静态资源,比如/css/**、/js/**、/images/**这类路径,如果你的请求是这些路径,自然会被直接放行。但如果是业务接口的话,这个可能性不大,不过还是可以检查下你的请求路径是不是属于默认放行的范围。
给你几个排查小步骤
- 先把
@Order(1)去掉,看看配置会不会生效,确认是不是优先级的问题。 - 检查项目里所有Spring Security相关的配置类,确保没有其他配置类的规则覆盖了你的设置。
- 开启Spring Security的调试日志,在
application.properties里加一行:
logging.level.org.springframework.security=DEBUG
这样你就能看到请求的拦截全过程,哪个过滤器处理了请求,认证有没有成功,规则有没有被应用,一目了然。
内容的提问来源于stack exchange,提问作者user152468

