Spring 4/5 全局 CORS 配置不起作用,给出“请求的资源上不存在‘Access-Control-Allow-Origin’标头’

Posted

技术标签:

【中文标题】Spring 4/5 全局 CORS 配置不起作用,给出“请求的资源上不存在‘Access-Control-Allow-Origin’标头’【英文标题】:Spring 4/5 global CORS configuration doesn't work giving `No 'Access-Control-Allow-Origin' header is present on the requested resource` 【发布时间】:2017-06-22 11:38:30 【问题描述】:

我正在尝试使用 HTTP `POST 通过http://localhost:3000 登录。

我得到以下信息:

XMLHttpRequest 无法加载 http://localhost:8080/api/auth/login。请求的资源上不存在“Access-Control-Allow-Origin”标头。 Origin 'http://localhost:3000' 因此不允许访问。

我已经像这样配置了我的 Spring 5.0.0.M4 和 Spring-Security 4.2.1.RELEASE 应用程序:

@SpringBootApplication
public class SpringBootApp extends WebMvcConfigurerAdapter 

    private boolean workOffline = true;
    private boolean setupSchema = false;
    private IGraphService graphService;
    private DbC conf;

    @Autowired
    public SpringBootApp(IGraphService graphService, DbC conf)
    
        this.graphService = graphService;
        this.conf = conf;
    

    public static void main(String[] args) throws Exception 
        SpringApplication.run(SpringBootApp.class, args);
    

    @Bean
    public Filter caseInsensitiveRequestFilter() 
        return new CaseInsensitiveRequestFilter();
    

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) 
        configurer.enable();
    

    @Override
    public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:3000")
                .allowedMethods("GET", "PUT", "POST", "DELETE","OPTIONS");
    

    @Bean
    public FilterRegistrationBean corsFilter() 
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://localhost:3000");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    

我不明白为什么全局 CORS 配置即使看起来配置正确也不起作用。

我已附加控制台和网络选项卡:

【问题讨论】:

我在 Spring 4 上遇到了同样的问题。我不得不升级到 5,因为他们决定弃用 Guava。我与之发生冲突,Datastax 包需要旧版本 令牌基于后端 JWT (github.com/svlada/springboot-security-jwt) 【参考方案1】:

在 dur 的帮助下。我发现 http://github.com/svlada/springboot-security-jwt 添加了一个 WebSecurityConfig,它覆盖了我的 Spring Boot 应用程序配置。

WebSecurityConfig 的配置部分中,我在其他任何内容之前添加了 cors(),如下所示:

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.cors()
        .and()
        .csrf().disable() // We don't need CSRF for JWT based authentication
        .exceptionHandling()
        .authenticationEntryPoint(this.authenticationEntryPoint)

        .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)

        .and()
            .authorizeRequests()
                .antMatchers(FORM_BASED_LOGIN_ENTRY_POINT).permitAll() // Login end-point
                .antMatchers(TOKEN_REFRESH_ENTRY_POINT).permitAll() // Token refresh end-point
                .antMatchers("/console").permitAll() // H2 Console Dash-board - only for testing
        .and()
            .authorizeRequests()
                .antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated() // Protected API End-points
        .and()
            .addFilterBefore(buildAjaxLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
            .addFilterBefore(buildJwtTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class);
    

然后我收到了 corsFilter 的错误。 Bean 必须是 CorsFilter 类型,但对我来说是 FilterRegistrationBean

所以我将 @SpringBootApplication 类中的 Bean 从

    @Bean
    public FilterRegistrationBean corsFilter() 
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://localhost:3000");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    

到:

    @Bean
    public CorsFilter corsFilter() 
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://localhost:3000");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    

我也删了

  @Override
    public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:3000")
                .allowedMethods("GET", "PUT", "POST", "DELETE","OPTIONS");
    

我可能不得不将这些配置移动到一个地方 - 最好完全删除 WebSecurityConfig

【讨论】:

使用提到的 CorsFilter bean 对我有用。这是在尝试 Spring Security 5 参考指南中提到的配置失败后:docs.spring.io/spring-security/site/docs/current/reference/html/…

以上是关于Spring 4/5 全局 CORS 配置不起作用,给出“请求的资源上不存在‘Access-Control-Allow-Origin’标头’的主要内容,如果未能解决你的问题,请参考以下文章

使用Java Config的全局CORS配置不起作用

使用 Java Config 的全局 CORS 配置不起作用

Sails.js 全局 CORS 配置不起作用,每条路线是

在 Spring Boot 应用程序中配置 cors。 Bean CorsConfigurationSource 不起作用

部署到 Google App Engine 时 Spring Boot CORS 配置不起作用

Spring Boot Cors 问题:尝试了所有方法,但 POST 不起作用