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

Spring-SAML认证成功后陷入无限重定向循环问题咨询

解决SAML认证后无限重定向:BasicAuthenticationFilter与SAMLAuthenticationProvider的冲突问题

我之前确实碰到过一模一样的场景!这种问题本质上是Spring Security过滤器链的执行逻辑或Provider匹配规则出了问题——SAML认证成功后,BasicAuthenticationFilter还在试图执行认证流程,而SAMLAuthenticationProvider根本不处理UsernamePasswordAuthenticationToken,抛出的异常会触发系统的重定向逻辑,最终形成无限循环。

给你几个经过验证的解决思路:

1. 让BasicAuthenticationFilter仅对未认证请求生效

你可以通过自定义过滤器逻辑,让Basic认证只在用户未被认证时触发,避免干扰已完成SAML认证的请求:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .anyRequest().authenticated()
            .and()
        .saml2Login() // 保留你的SAML登录配置
            .and()
        .addFilterBefore(new BasicAuthenticationFilter(authenticationManager()) {
            @Override
            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
                // 已认证则直接跳过Basic认证流程
                Authentication auth = SecurityContextHolder.getContext().getAuthentication();
                if (auth != null && auth.isAuthenticated() && !(auth instanceof AnonymousAuthenticationToken)) {
                    chain.doFilter(request, response);
                    return;
                }
                super.doFilterInternal(request, response, chain);
            }
        }, UsernamePasswordAuthenticationFilter.class);
}

2. 为AuthenticationManager配置Provider匹配规则

问题的核心是AuthenticationManager错误地把UsernamePasswordAuthenticationToken交给了SAMLAuthenticationProvider处理。你可以为不同的Token类型绑定专属Provider,避免交叉调用:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    // 配置Basic认证专属的Provider
    DaoAuthenticationProvider basicAuthProvider = new DaoAuthenticationProvider();
    basicAuthProvider.setUserDetailsService(userDetailsService);
    basicAuthProvider.setPasswordEncoder(passwordEncoder);

    // 配置SAML认证Provider
    SAMLAuthenticationProvider samlAuthProvider = new SAMLAuthenticationProvider();
    // 这里添加你的SAML Provider配置(比如用户信息映射等)

    // 让AuthenticationManager根据Token类型匹配对应的Provider
    auth.authenticationProvider(basicAuthProvider)
        .authenticationProvider(samlAuthProvider);
}

Spring Security的ProviderManager会自动根据Token的类型选择合适的Provider,不会再把Basic认证的Token传给SAMLProvider。

3. 直接禁用不必要的BasicAuthenticationFilter

如果你的系统根本不需要Basic认证方式,这是最直接的解决方案:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .anyRequest().authenticated()
            .and()
        .saml2Login()
            .and()
        .httpBasic().disable(); // 彻底禁用Basic认证过滤器
}

另外,你可以顺便检查下SecurityContext的持久化状态——有时候SAML认证成功后,SecurityContext没有被正确存入Session,导致后续请求被判定为未认证,再次触发Basic认证逻辑。可以通过调试SecurityContextHolder.getContext()在认证前后的状态来确认。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:44:00