Spring Boot 3.1+Spring Security与Angular 16的CORS问题求助
解决Spring Boot 3.1 + Spring Security跨域/login接口CORS错误的方案
1. 确保Spring Security的CORS配置覆盖/login端点且顺序正确
Spring Security过滤器链的执行顺序直接影响CORS规则生效范围,cors()配置必须优先于权限校验、CSRF等配置,否则/login请求可能绕过CORS处理逻辑。
修改你的SecurityConfig配置类:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 先启用CORS配置 .cors(cors -> cors.configurationSource(corsConfigurationSource())) .csrf(csrf -> csrf.disable()) // 若无需CSRF可暂时关闭测试,后续按需开启 .authorizeHttpRequests(auth -> auth // 放行/login的OPTIONS预检请求和POST登录请求 .requestMatchers(HttpMethod.OPTIONS, "/login").permitAll() .requestMatchers("/login").permitAll() .anyRequest().authenticated() ); return http.build(); } // 定义全局CORS配置源 @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); // 指定允许的客户端Origin configuration.setAllowedOrigins(List.of("http://client.example.com")); // 允许的HTTP方法,包含预检OPTIONS和登录用的POST configuration.setAllowedMethods(List.of("GET", "POST", "OPTIONS")); // 允许的请求头,根据登录请求实际需求调整 configuration.setAllowedHeaders(List.of("Authorization", "Content-Type")); // 允许携带凭证(如Cookie) configuration.setAllowCredentials(true); // 暴露给前端的响应头(若需要返回Token等) configuration.setExposedHeaders(List.of("Authorization")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); // 将配置应用到所有端点,确保/login被覆盖 source.registerCorsConfiguration("/**", configuration); return source; } }
2. 自定义/login接口的响应头兜底处理
如果你的/login是自定义Controller接口,通过WebClient调用Keycloak后返回响应,若Spring的CORS过滤器未生效,可在接口方法中手动添加CORS头作为兜底:
@PostMapping("/login") public ResponseEntity<?> login(@RequestBody LoginRequest request) { // 调用Keycloak获取Token的逻辑 Mono<KeycloakTokenResponse> tokenResponse = webClient.post() .uri("http://keycloak.example.com/realms/your-realm/protocol/openid-connect/token") .bodyValue(buildLoginFormData(request)) .retrieve() .bodyToMono(KeycloakTokenResponse.class); return tokenResponse.map(response -> ResponseEntity.ok() .header("Access-Control-Allow-Origin", "http://client.example.com") .header("Access-Control-Allow-Credentials", "true") .body(response) ).block(); }
3. 移除WebFlux CORS配置避免冲突
若之前添加了WebFlux独立的CORS配置,会和Spring Security的CORS配置产生冲突(Security过滤器优先级更高),需删除重复配置,仅保留Security层面的CORS规则。
4. 验证预检请求响应
用curl测试OPTIONS预检请求,确认响应包含正确的CORS头:
curl -X OPTIONS http://api.example.com/login \ -H "Origin: http://client.example.com" \ -H "Access-Control-Request-Method: POST"
正常响应应包含以下头信息:
Access-Control-Allow-Origin: http://client.example.com
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Allow-Credentials: true
内容的提问来源于stack exchange,提问作者gs_it
相关产品推荐
相关产品推荐

