Spring Boot Security跨域API问题:安全接口跨域调用报错
解决Spring Security+JWT下受保护接口跨域问题
问题核心
浏览器发起跨域请求时会先发送OPTIONS预检请求,该请求不带Authorization头,会被Spring Security拦截判定为未授权;同时现有CORS配置缺少必要的头信息,导致跨域验证失败。
具体修复步骤
1. 放行OPTIONS预检请求
在SecurityConfig的configure方法中,添加对所有OPTIONS请求的全局放行,确保预检请求能正常通过:
@Override protected void configure(HttpSecurity http) throws Exception { http .cors().and() .csrf().disable() .authorizeRequests() .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 新增:放行所有OPTIONS请求 .antMatchers("/ifrs/api/v1/user/token").permitAll() .anyRequest().authenticated() .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class) .exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)); }
2. 完善CORS配置
补充允许的请求头、暴露的响应头,确保跨域请求能正常携带和读取必要信息:
@Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("*")); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); configuration.setAllowedHeaders(Arrays.asList("*")); // 允许所有请求头(包括Authorization) configuration.setExposedHeaders(Arrays.asList("Authorization")); // 暴露响应头给前端 configuration.setAllowCredentials(true); // 允许携带凭证(如Cookie,按需开启) UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; }
3. 优化JWT过滤器(可选,增强鲁棒性)
显式判断OPTIONS请求并直接放行,避免过滤器逻辑意外拦截预检请求:
@Override protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // OPTIONS请求直接放行 if (HttpMethod.OPTIONS.name().equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); filterChain.doFilter(request, response); return; } try { // 原有过滤器逻辑... String token = request.getHeader("Authorization"); // ...其余代码保持不变 } catch (ExpiredJwtException e) { throw e; } catch (Exception e) { throw e; } }
4. 移除Controller上的@CrossOrigin注解(可选)
由于已通过Spring Security全局配置CORS,Controller层面的@CrossOrigin会与全局配置冲突,建议移除。
为什么原有@CrossOrigin无效?
Spring Security的过滤器链执行优先级高于Controller的拦截器,当预检请求被Security拦截时,还未到@CrossOrigin生效的阶段,因此必须在Security层面完成CORS配置并放行OPTIONS请求。
内容的提问来源于stack exchange,提问作者mehnet ali
相关产品推荐
相关产品推荐

