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

Spring Boot集成SAML对接ADFS出现CORS错误如何阻止请求重定向

问题背景

我基于公开的SAML示例项目搭建了集成SAML实现ADFS单点登录的Spring Boot服务端,和原示例项目不同的是我使用Gradle而非Maven进行构建。
目前登录功能和其他常规功能运行正常,仅存在CORS错误,浏览器侧会出现以下三类报错:

  • 情况一
    情况一报错1
    情况一报错2
  • 情况二
    情况二报错1
    情况二报错2
    情况二报错3
  • 直接访问对应URL时的报错
    直接访问报错

Spring服务端始终抛出相同错误,日志如下:

2021-09-02 09:48:25.042 DEBUG 80412 --- [io-10009-exec-5] o.a.tomcat.util.net.jsse.JSSESupport     : Error trying to obtain a certificate from the client
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at java.base/sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:556) ~[na:na]
    at org.apache.tomcat.util.net.jsse.JSSESupport.getPeerCertificateChain(JSSESupport.java:106) ~[tomcat-embed-core-9.0.41.jar:9.0.41]

我已经尝试了十多种CORS实现方案,包括@CrossOrigin注解和Global CORS configutation,均未达到预期效果。
当前我向Spring服务端发送Get-Request时,服务端没有处理该请求而是直接将其重定向到ADFS,由此触发报错,这是因为ADFS本身无法处理这类请求。
请问我该如何阻止Spring服务端将Get-Request重定向到ADFS?

解决方案

你遇到的问题本质不是CORS配置错误,而是Spring Security SAML的认证拦截优先级高于CORS配置,且未认证请求默认触发重定向到身份提供商的逻辑,调整Spring Security配置即可解决:

  1. 首先调整CORS过滤器优先级,让它在Spring Security认证过滤器之前执行,同时放开预检请求、公共接口的认证限制,修改未认证异步请求的处理逻辑,不再返回重定向而是返回401状态码:
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        // 优先启用CORS,Spring会自动读取你定义的CorsConfigurationSource Bean
        .cors().and()
        .authorizeRequests()
        // 所有OPTIONS预检请求直接放行
        .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
        // 把不需要走ADFS认证的接口路径加到此处,比如公共接口、健康检查接口
        .antMatchers("/api/public/**", "/actuator/**").permitAll()
        .anyRequest().authenticated()
        .and()
        // 异步请求未认证时返回401,不触发重定向到ADFS的逻辑
        .exceptionHandling()
        .defaultAuthenticationEntryPointFor(
            new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED),
            // 匹配前端异步请求,可根据你的业务场景调整匹配规则
            new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest")
        )
        // 此处保留你原有SAML相关的配置即可
        .and()
        .apply(samlConfigurer());
}
  1. 如果你要全局关闭所有未认证请求的重定向逻辑,直接替换默认的认证入口点即可:
http.exceptionHandling()
    .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
  1. 排查SSL日志报错:日志中的SSLPeerUnverifiedException是因为Tomcat开启了客户端证书校验,如果你不需要双向SSL认证,可以在application配置文件中关闭:
server.ssl.client-auth=none

注意:如果你的全局CORS配置是通过实现WebMvcConfigurer接口配置的,Spring Security默认不会读取该配置,需要单独将CorsConfigurationSource注册为Bean:

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    // 替换为你的前端实际域名,不要直接写*
    configuration.setAllowedOrigins(Arrays.asList("https://your-frontend-domain.com"));
    configuration.setAllowedMethods(Arrays.asList("GET","POST","PUT","DELETE","OPTIONS"));
    configuration.setAllowedHeaders(Arrays.asList("*"));
    configuration.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 04:18:03