【问题标题】:CORS issue - Response to preflight request doesn't pass access control check:CORS 问题 - 对预检请求的响应未通过访问控制检查:
【发布时间】: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 保护。

【问题讨论】:

标签: java reactjs spring-boot cors okta


【解决方案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

【讨论】:

  • 尝试了不同线程中建议的各种不同解决方案。但这是唯一帮助我的人。谢谢!
猜你喜欢
  • 2019-09-09
  • 2019-01-04
  • 1970-01-01
  • 2020-08-14
  • 1970-01-01
  • 2020-09-07
  • 2021-09-26
  • 2017-04-28
  • 2017-11-09
相关资源
最近更新 更多