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

Spring Authorization Server 0.3.1 CORS问题:授权码流程401错误排查

问题分析与解决方案

核心问题

你的授权服务器存在多个SecurityFilterChain执行顺序冲突,导致针对/oauth2/token端点的CORS配置完全未生效:

  • WebSecurityConfiguration中定义的filterChain未指定@Order,默认优先级最低(数值最大)
  • 授权服务器的authorizationServerSecurityFilterChain标注了@Order(1),会优先处理所有请求(包括/oauth2/token),但该链未配置CORS规则
  • 前端发起预请求(OPTIONS)到/oauth2/token时,授权服务器的过滤器链未处理跨域,反而触发了重定向(比如未认证跳转登录页),违反了CORS预请求禁止重定向的规则,最终导致报错。

修复步骤

1. 合并CORS配置到授权服务器过滤器链

删除WebSecurityConfiguration中的filterChain Bean,将CORS配置直接整合到authorizationServerSecurityFilterChain中:

@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
    OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
    // 添加CORS配置
    http.cors().configurationSource(corsConfigurationSource())
        .and()
        .formLogin(Customizer.withDefaults());
    return http.build();
}

// 保留原有的跨域配置方法,移至当前配置类中
private CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    boolean useAllowedOriginPatterns = allowedOrigins.isEmpty() || allowedOrigins.contains("*");
    if (useAllowedOriginPatterns) {
        configuration.setAllowedOriginPatterns(Collections.singletonList(CorsConfiguration.ALL));
    } else {
        configuration.setAllowedOrigins(new ArrayList<>(allowedOrigins));
    }
    configuration.setAllowedMethods(Collections.singletonList(CorsConfiguration.ALL));
    configuration.setAllowCredentials(true);
    configuration.setAllowedHeaders(Collections.singletonList(CorsConfiguration.ALL));

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    // 针对/oauth2/token端点单独配置,同时保留全局规则
    source.registerCorsConfiguration("/oauth2/token", configuration);
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

// 保留原有standardSecurityFilterChain配置
@Bean
@Order(2)
public SecurityFilterChain standardSecurityFilterChain(HttpSecurity http) throws Exception {
    http
            .authorizeHttpRequests((authorize) -> authorize
                    .anyRequest().authenticated()
            )
            .formLogin(Customizer.withDefaults());
    return http.build();
}

2. 简化冗余配置

如果WebSecurityConfiguration仅包含全局方法安全和CORS配置,可简化为:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration {
    // 仅保留全局方法安全注解,CORS配置已移至授权服务器过滤器链
}

3. 额外建议

  • Authorization Code流程的标准实践是由后端客户端服务(而非前端)发起/oauth2/token请求:前端仅负责跳转授权页面、接收授权码,再将授权码传给后端,由后端兑换token。这种方式既能避免跨域问题,也能避免暴露客户端密钥,提升安全性。
  • 若必须让前端直接请求/oauth2/token,需确保OAuth2客户端配置为public类型(无需客户端密钥),并在授权服务器的客户端注册中设置正确的redirect_uri和allowed_origins。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:25:39