Spring Security WebFlux如何配置指定路径跳过认证与授权
问题根因
你使用的WebSecurityCustomizer是Spring Security Servlet栈专属配置,在WebFlux响应式环境下不会被加载生效,这是你配置了ignoring规则但自定义认证过滤器依旧触发的核心原因。
另外authorizeExchange中配置的permitAll()仅代表跳过授权校验,不会中断过滤器链执行,链上注册的所有认证过滤器依旧会运行,因此无法阻止自定义AuthenticationWebFilter的逻辑执行。
解决方案
方案1(推荐):限定安全过滤链生效范围
通过securityMatcher直接指定当前安全过滤链仅拦截需要认证的路径,将需要公开访问的路径完全排除在Spring Security过滤链之外,从根源上避免这些路径经过任何安全过滤器(包括你自定义的认证过滤器),性能开销最低。
直接修改你的SecurityWebFilterChain配置即可,删除原有不生效的WebSecurityCustomizer配置:
@Bean SecurityWebFilterChain springSecurityFilterChain( ServerHttpSecurity http, AuthenticationWebFilter authenticationWebFilter ) { return http // 排除公开路径,仅其余路径进入安全过滤链 .securityMatcher(new NegatedServerWebExchangeMatcher( ServerWebExchangeMatchers.pathMatchers("/actuator/**", "/login/**") )) .httpBasic(HttpBasicSpec::disable) .csrf(CsrfSpec::disable) .formLogin(FormLoginSpec::disable) .anonymous(AnonymousSpec::disable) .logout(LogoutSpec::disable) .authorizeExchange((authorize) -> authorize .anyExchange().authenticated() ) .addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION) .build(); }
该配置等价于Servlet栈下
web.ignoring()的效果,公开路径不会经过任何Spring Security逻辑,不需要再额外给这些路径配置permitAll()。
方案2:自定义过滤器内部加路径判断
如果你不需要调整过滤链的整体匹配范围,可以直接在自定义AuthenticationWebFilter的执行逻辑最前端增加路径判断,匹配到公开路径时直接跳过当前过滤器的认证逻辑,放行到下一个过滤器:
// 自定义AuthenticationWebFilter内的代码片段 private static final PathPatternParser PATTERN_PARSER = new PathPatternParser(); private static final List<PathPattern> IGNORE_PATHS = List.of( PATTERN_PARSER.parse("/actuator/**"), PATTERN_PARSER.parse("/login/**") ); @Override public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); // 匹配到公开路径直接跳过认证逻辑 boolean matchIgnore = IGNORE_PATHS.stream() .anyMatch(pattern -> pattern.matches(request.getPath().pathWithinApplication())); if (matchIgnore) { return chain.filter(exchange); } // 原有认证业务逻辑 // ... }
注意事项
- WebFlux响应式栈没有和Servlet栈完全等价的
WebSecurityCustomizerignoring配置,全局排除路径只能通过securityMatcher实现 - 仅配置
permitAll()不会跳过过滤器链执行,所有注册的安全过滤器依旧会运行,公开接口、静态资源等建议直接排除在过滤链外减少不必要的性能开销
内容的提问来源于stack exchange,提问作者Jordi
相关产品推荐
相关产品推荐

