Spring Authorization Server 1.0.0:请求/oauth2/token遇JavaScript跨域错误
问题分析
你遇到的核心矛盾是:浏览器发起/oauth2/token请求时会触发CORS预检(OPTIONS)请求,而Spring Security拦截了该匿名预检请求并返回Access Denied,导致CORS验证失败;但Postman无需发送预检请求,且能正确传递客户端凭证,因此可以正常获取令牌。
解决方案
1. 配置Spring Security允许CORS及预检请求
在Spring Security配置中,需优先启用CORS支持,明确允许前端源、必要HTTP方法(含OPTIONS)和请求头,同时放开预检请求的权限:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 先配置CORS,优先级高于权限控制 .cors(cors -> cors.configurationSource(corsConfigurationSource())) .authorizeHttpRequests(auth -> auth // 允许OPTIONS请求直接通过,无需认证 .requestMatchers(HttpMethod.OPTIONS, "/oauth2/token").permitAll() // 其他请求需认证 .anyRequest().authenticated() ) // 保留原有授权服务器与资源服务器配置 .oauth2AuthorizationServer(OAuth2AuthorizationServerConfigurer::authorizationServer) .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); return http.build(); } @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration corsConfig = new CorsConfiguration(); // 允许你的Vue应用源 corsConfig.setAllowedOrigins(Collections.singletonList("http://127.0.0.1:9010")); // 允许必要的HTTP方法,含预检的OPTIONS corsConfig.setAllowedMethods(Arrays.asList("GET", "POST", "OPTIONS")); // 允许请求中携带的头信息 corsConfig.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type")); // 允许携带跨域凭证 corsConfig.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); // 对所有接口应用CORS配置 source.registerCorsConfiguration("/**", corsConfig); return source; } }
2. 调整客户端类型与授权流程
如果你的客户端是confidential类型(需客户端密钥),前端SPA无法安全存储密钥,直接请求/oauth2/token存在安全风险,且浏览器可能因跨域限制无法正确传递Basic Auth凭证。建议:
- 将客户端改为
public类型,结合PKCE授权码流程(Spring Authorization Server默认支持PKCE) - 或通过后端代理转发
/oauth2/token请求,由后端处理客户端凭证
3. 验证预检请求状态
修改配置后重启服务器,在浏览器控制台查看OPTIONS请求的响应状态码,若返回200则预检通过,后续POST请求即可正常发送。
关键原因说明
- 浏览器跨域请求会先发送OPTIONS预检请求,该请求不携带任何认证信息(处于匿名状态),Spring Security默认拦截未认证请求,因此返回
Access Denied - Postman不会触发CORS预检,直接发送POST请求并传递客户端凭证(如Basic Auth),因此能正常获取令牌
内容的提问来源于stack exchange,提问作者Christian Osterrieder
相关产品推荐
相关产品推荐

