Spring Security中PermitAll()失效,非/data/**接口返回401求助
问题根源
你的JWT过滤器被应用到了所有请求(包括开放接口和错误页面),导致非/data/**的请求因未携带JWT而返回401。同时配置中的冗余规则和过滤器优先级设置加剧了这个问题。
解决方案
1. 修改JWT过滤器,仅对/data/**接口做校验
在JwtAuthFilter的doFilterInternal方法开头添加路径判断,非/data前缀的请求直接放行:
@Override protected void doFilterInternal( @Nullable HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable FilterChain filterChain ) throws IOException, ServletException { assert request != null; assert response != null; assert filterChain != null; // 仅对/data/**路径的请求执行JWT校验 String requestUri = request.getRequestURI(); if (!requestUri.startsWith("/data/")) { filterChain.doFilter(request, response); return; } String jwt = parseJwt(request); if (jwt != null && validateToken(jwt)) { filterChain.doFilter(request, response); } else { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } }
2. 简化Security配置类
调整DataSecurity配置,移除冗余规则,明确过滤器作用范围:
@EnableWebSecurity public class DataSecurity extends WebSecurityConfigurerAdapter { @Bean public JwtAuthFilter jwtAuthenticationFilter() { return new JwtAuthFilter(); } @Override protected void configure(HttpSecurity http) throws Exception { http.cors() .and() .csrf().disable() .httpBasic().disable() .logout().disable() .formLogin().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() .antMatchers("/data/**").authenticated() .anyRequest().permitAll(); // 将JWT过滤器添加到认证过滤器之前 http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); } @Override public void configure(WebSecurity web) { // 让开放接口和错误页面完全跳过Security过滤器链 web.ignoring().antMatchers("/oauth/**", "/callback/**", "/save/**", "/error"); } }
3. 移除过滤器上的@Order注解
删除JwtAuthFilter类上的@Order(Ordered.HIGHEST_PRECEDENCE),避免全局高优先级导致的过滤器范围失控。
修改说明
- 过滤器内的路径判断确保只有
/data/**请求会触发JWT校验,其他请求直接放行。 WebSecurity.ignoring()让开放接口完全跳过Security处理,提升性能同时避免误拦截。- 简化的
HttpSecurity配置明确授权规则:/data/**需认证(由JWT过滤器完成),其余请求无限制。
内容的提问来源于stack exchange,提问作者eva_mila
相关产品推荐
相关产品推荐

