Spring Security如何移除指定URL认证?配置公开URL仍被拦截401
配置问题定位
- 自定义
restAuthenticationFilter()未限定拦截范围,全局生效
你通过addFilterBefore将该认证过滤器加入安全链时,没有为它配置任何路径匹配规则,所有请求(包括你声明的公开接口、Swagger路径)都会被它执行内部Token校验逻辑。该校验逻辑在检测不到合法Token时会直接返回401,请求根本不会流转到后续authorizeRequests环节的permitAll规则判定,这也是调试时观察到公开URL仍被该过滤器处理的直接原因。 - 混淆了
web.ignoring()的作用边界web.ignoring()配置的路径,会完全跳过Spring Security原生过滤链;但你手动注册的自定义过滤器,是被硬编入安全链执行顺序的,不受ignoring()的跳过规则影响——哪怕路径在忽略列表中,只要过滤器本身没有路径判定逻辑,就会被触发执行。 - 原配置的路径匹配逻辑和过滤器执行顺序冲突
你最初通过NegatedRequestMatcher将非/authentication/**的路径判定为受保护路径,并为这些路径配置了403响应入口点,但由于自定义过滤器的执行顺序远早于权限判定环节,公开路径的请求被过滤器先拦截返回401,根本触发不到后续的异常处理和权限放行逻辑。
修复方案
- 为自定义
restAuthenticationFilter()增加公开路径跳过逻辑
在过滤器的请求处理入口添加路径匹配判定,命中公开路径时直接放行,不执行Token校验:// 统一维护公开路径匹配规则 private static final RequestMatcher PUBLIC_URL_MATCHER = new OrRequestMatcher( new AntPathRequestMatcher("/authentication/**"), new AntPathRequestMatcher("/v2/api-docs"), new AntPathRequestMatcher("/configuration/ui"), new AntPathRequestMatcher("/swagger-resources/**"), new AntPathRequestMatcher("/configuration/security"), new AntPathRequestMatcher("/swagger-ui.html"), new AntPathRequestMatcher("/webjars/**") ); @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { // 命中公开路径直接放行,不执行校验逻辑 if (PUBLIC_URL_MATCHER.matches(request)) { chain.doFilter(request, response); return; } // 原有Token解析、认证逻辑... } - 简化HttpSecurity权限配置,移除冲突的反向路径判定
不需要额外维护PROTECTED_URLS的反向匹配规则,直接按优先级在authorizeRequests中声明公开路径的放行规则:http .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authenticationProvider(tokenAuthProv()) .addFilterBefore(restAuthenticationFilter(), AnonymousAuthenticationFilter.class) .authorizeRequests() // 公开路径直接放行 .mvcMatchers( "/authentication/login", "/authentication/registrarusuario", "/v2/api-docs", "/configuration/ui", "/swagger-resources/**", "/configuration/security", "/swagger-ui.html", "/webjars/**" ).permitAll() // 其余所有请求需要认证 .anyRequest().authenticated() .and() .csrf().disable() .formLogin().disable() .httpBasic().disable() .logout().disable(); - 清理冗余的WebSecurity层配置
由于已经在自定义过滤器和权限配置中明确了公开路径规则,不需要再在configure(WebSecurity web)方法中重复配置忽略规则,避免多层路径匹配逻辑不一致带来的维护问题。
注意:Spring Security的规则匹配按声明顺序优先级执行,自定义过滤器的执行优先级高于所有权限判定规则,必须在过滤器层完成公开路径的放行,否则任何
permitAll配置都不会生效。
内容的提问来源于stack exchange,提问作者Douglas Pacheco
相关产品推荐
相关产品推荐

