You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring WebFlux如何实现分路径差异化认证失败响应配置

Spring WebFlux 实现分路径差异化认证失败处理

原有业务规则

  • 系统基于Session Cookie完成请求身份校验
  • 匹配/api/**的请求认证失败时,直接返回401状态码供前端拦截处理
  • 非/api/**路径的请求认证失败时,服务端返回登录页引导用户登录

原有Spring MVC实现参考

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
        .anyRequest()
        .authenticated()
        .and()
        .formLogin()
        .and()
        .csrf()
        .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
        .and()
        .exceptionHandling()
        .defaultAuthenticationEntryPointFor(
            new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED),
            new AntPathRequestMatcher("/api/**")
        )
        .and()
        .cors();
    }
}

WebFlux迁移问题

WebFlux环境下的ServerHttpSecurity没有提供Servlet环境中defaultAuthenticationEntryPointFor的直接等价方法,全局配置单一authenticationEntryPoint会导致所有路径认证失败逻辑统一,无法满足差异化处理要求,初始问题配置如下:

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain filterChain(ServerHttpSecurity http)  {
        return http
                .authorizeExchange()
                .pathMatchers("/login/**")
                .permitAll()
                .anyExchange()
                .authenticated()
                .and()
                .formLogin()
                .and()
                .csrf()
                .disable()
                .exceptionHandling()
                // 全局配置401返回,导致非API路径无法跳转登录页
                .authenticationEntryPoint(new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED))
                .and()
                .build();
    }
}

实现方案

通过自定义委托型ServerAuthenticationEntryPoint,在认证失败触发时先判断请求路径,匹配对应规则后选择对应的处理逻辑即可,和MVC下多EntryPoint匹配的效果完全一致。
完整可运行配置如下:

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain filterChain(ServerHttpSecurity http) {
        // WebFlux专用路径匹配器,不要使用Servlet环境的AntPathRequestMatcher
        PathPatternParserServerWebExchangeMatcher apiPathMatcher =
                new PathPatternParserServerWebExchangeMatcher("/api/**");
        // API路径认证失败处理:返回401状态码
        ServerAuthenticationEntryPoint apiUnauthEntryPoint =
                new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED);
        // 页面路径认证失败处理:跳转登录页,路径和formLogin配置保持一致
        ServerAuthenticationEntryPoint pageLoginEntryPoint =
                new RedirectServerAuthenticationEntryPoint("/login");

        // 委托入口点:按路径分发到对应处理逻辑
        ServerAuthenticationEntryPoint delegatingEntryPoint = (exchange, authEx) ->
                apiPathMatcher.matches(exchange)
                        .flatMap(matchResult -> matchResult.isMatch()
                                ? apiUnauthEntryPoint.commence(exchange, authEx)
                                : pageLoginEntryPoint.commence(exchange, authEx)
                        );

        return http
                .authorizeExchange()
                .pathMatchers("/login/**")
                .permitAll()
                .anyExchange()
                .authenticated()
                .and()
                .formLogin()
                .and()
                .csrf()
                .disable()
                .cors()
                .exceptionHandling()
                .authenticationEntryPoint(delegatingEntryPoint)
                .and()
                .build();
    }
}

注意事项

  • 路径匹配必须使用WebFlux专属的PathPatternParserServerWebExchangeMatcher,Servlet环境的AntPathRequestMatcher在响应式环境下会出现路径匹配异常。
  • 如果自定义了表单登录页路径,比如配置.formLogin().loginPage("/custom-login"),需要同步修改RedirectServerAuthenticationEntryPoint的跳转路径为自定义登录页地址。
  • 需要新增更多路径的差异化认证失败逻辑时,直接在委托入口点中增加对应匹配分支即可。

内容的提问来源于stack exchange,提问作者altair

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 21:31:10