CORS 问题 - 对预检请求的响应未通过访问控制检查:

Posted

技术标签:

【中文标题】CORS 问题 - 对预检请求的响应未通过访问控制检查:【英文标题】:CORS issue - Response to preflight request doesn't pass access control check: 【发布时间】:2019-12-02 16:03:09 【问题描述】:

我正在研究 reactjs 前端,在后端使用弹簧引导。 我正在尝试从前端调用端点,如下所示:

testOktaTokenAtRest(data) 
  var oauth=JSON.parse(localStorage.getItem('okta-token-storage'))
  console.log("toekn is: ==>  "+oauth.accessToken.tokenType + 
  oauth.accessToken.accessToken)
  console.log("toekn received from action is inside this obj: ",data)
  var searchCriteria = JSON.stringify(data.data)
  console.log("searchCriteria data -------: " , searchCriteria)

 let _headerForSearch=
    auth : 'Bearer ' + oauth.accessToken.accessToken 
  
  $.ajax(
    method: "post",
    url: "http://localhost:8000/ckcapp/api/posttest",
    contentType: "application/json",
    dataType: "json",
    data:searchCriteria,
    beforeSend: function (xhr) 
      xhr.setRequestHeader("Authorization", _headerForSearch.auth);
    ,
    success: function(response) 

      console.log("response from okta enabled get api is: ",response)
    ,
    error: function(xhr, status, error) 
      console.log("error from okta enabled get api is: ",xhr.responseText 
     + " " +status + " " + error );
    
  );


  

当我提出请求时,我收到以下错误:-

访问 XMLHttpRequest 在 'http://localhost:8000/ckcapp/api/posttest' 来自原点“http://localhost:3000”已被 CORS 策略阻止: 对预检请求的响应未通过访问控制检查:否 'Access-Control-Allow-Origin' 标头出现在请求的 资源。

我的 spring-boot 应用程序有以下配置:

CORSFilter
    public class CORSFilter implements Filter 


    private static final String ONE_HOUR = "3600";

      @Override
      public void init(FilterConfig filterConfig) throws ServletException 
    
      

      @Override
      public void doFilter(ServletRequest req, ServletResponse res, 
    FilterChain chain) throws IOException, ServletException 
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", 
    "http://localhost:3000");
        response.setHeader("Access-Control-Allow-Methods", "POST, PUT, 
    GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", ONE_HOUR);
        response.setHeader("Access-Control-Request-Headers", 
    "authorization,content-type");
        response.setHeader("Access-Control-Allow-Headers", "X-Requested- 
    With,Origin,Content-Type, Accept, x-device-user-agent, Content-Type");

        if (req instanceof HttpServletRequest) 
           HttpServletRequest httpServletRequest = (HttpServletRequest) 
    req;
           if (httpServletRequest.getHeader(HttpHeaders.ORIGIN) != null
              && 
      httpServletRequest.getMethod().equals(HttpMethod.OPTIONS.name())
              && 
    httpServletRequest.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) 
    != 
    null) 

              return;
           
        
        chain.doFilter(req, res);
      

      @Override
      public void destroy() 
       
    

我将端点称为:

 @RestController
    @CrossOrigin(origins = "http://localhost:3000")
    public class CkcOktaController 
        @PostMapping("/api/posttest")
    @PreAuthorize("hasAuthority('SCOPE_email')")
    public String setString(@RequestBody CustomerDetailsNew 
        customerDetails) 
        System.out.println("In post method ");
        System.out.println("text :" + customerDetails.toString());
        System.out.println("text :" + customerDetails.getEntityId());
        return "Success";
    
    

我想我缺少一些配置。

应用程序受 OKTA 保护。

【问题讨论】:

我认为您需要处理预检请求。blog.morethancode.dev/… 【参考方案1】:

我通常使用 bean 来配置我的 CORS 设置。这是来自recent blog post:

@Bean
public FilterRegistrationBean<CorsFilter> simpleCorsFilter() 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.setAllowedOrigins(Collections.singletonList("*"));
    config.setAllowedMethods(Collections.singletonList("*"));
    config.setAllowedHeaders(Collections.singletonList("*"));
    source.registerCorsConfiguration("/**", config);
    FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
    bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return bean;

【讨论】:

这个基于过滤器的配置对我来说效果很好。有人可以帮我理解,为什么另一个配置,即添加 @Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer @Override public void addCorsMappings(CorsRegistry registry) registry.addMapping("/**").allowedOrigins("*").allowCredentials(true).maxAge(3600); 不起作用?大多数相关讨论都建议使用这种方法,但对我不起作用。 当我尝试这个时,我遇到了以下情况: -Control-Allow-Origin”响应标头。要允许凭据访问一组来源,请明确列出它们或考虑改用“allowedOriginPatterns”。 使用最新版本的 Spring Boot,如果需要通配符支持,则必须使用 allowedOriginPatterns("*")。或者使用allowedPatterns() 明确定义事物。也可以在 YAML 中定义,例如:allowed-origins: "http://localhost:8100,http://localhost:9000"【参考方案2】:

我在使用带有 Spring JWT 的 React 时遇到了与 CORS 策略阻止的类似问题。

在我的 SecurityConfigurer 类中添加了http.cors() 来解决

@EnableWebSecurity
public class SecurityConfigurer extends WebSecurityConfigurerAdapter 
    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.cors().and().csrf().disable().......
    

控制器

@CrossOrigin(origins = "http://localhost:3000")
@RestController

【讨论】:

尝试了不同线程中建议的各种不同解决方案。但这是唯一帮助我的人。谢谢!

以上是关于CORS 问题 - 对预检请求的响应未通过访问控制检查:的主要内容,如果未能解决你的问题,请参考以下文章

为啥 CORS 错误“对预检请求的响应未通过访问控制检查”?

CORS 问题 - 对预检请求的响应未通过访问控制检查:

CORS WCF:对预检请求的响应未通过访问控制

cors(cors 策略:对预检请求的响应未通过访问控制检查)角度 7 中的错误

OAuth 中的 CORS:对预检请求的响应未通过访问控制检查

角 POST 请求被 CORS 策略阻止:对预检请求的响应未通过访问控制检查