注释 CrossOrigin 在 Spring Boot 中不起作用

Posted

技术标签:

【中文标题】注释 CrossOrigin 在 Spring Boot 中不起作用【英文标题】:Annotation CrossOrigin not working in Spring boot 【发布时间】:2019-09-18 03:03:48 【问题描述】:

我有一个公开了一些端点的 Spring Boot 应用程序。我想从 React 应用程序向这些端点发出请求,但它一直给我 CORS 问题:

在以下位置访问 XMLHttpRequest 'localhost:9090/helios-admin/api/dashboard/clients?page=0&size=30' 来自原点“http://localhost:3000”已被 CORS 策略阻止: 跨源请求仅支持协议方案:http, 数据,铬,铬扩展,https。

所以我尝试对我的所有方法以及 Controller 类使用 @CrossOrigin 注释,但错误是相同的。 我的 react 应用中的 get 请求如下所示:

constructor() 
        this.url = 'localhost:9090/helios-admin/api/dashboard/clients?page=0&size=30';
    

    getProjectStatusById(projectId) 
        Axios.get(this.url).then(res=>
            console.log(res.data);
        )
    

缺少什么?

编辑 在我的 Spring Boot 应用程序中,我只有这个类来配置安全性:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 



    @Autowired
    SysdataUserDetailsService sysdataUserDetailsService;



    @Autowired
    private JwtAuthEntryPoint jwtAuthEntryPoint;



    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth
                .userDetailsService(sysdataUserDetailsService)
                .passwordEncoder(encoder());
    



    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.cors().and().csrf().disable().authorizeRequests()
                .antMatchers(PathConstants.USER_AUTH +"/**", PathConstants.HELIOS+"/dashboard/**").permitAll()
                .antMatchers(HttpMethod.GET, "/"+PathConstants.PROCESS_DEFINITION+"/**").permitAll()
                .antMatchers(HttpMethod.POST, "/"+PathConstants.PROCESS_DEFINITION+"/**").permitAll()
                .antMatchers(HttpMethod.GET, "/"+PathConstants.PROCESS_INSTANCE+"/**").permitAll()
                //.anyRequest().authenticated()
                .anyRequest().permitAll()
                .and()
                .exceptionHandling().authenticationEntryPoint(jwtAuthEntryPoint).and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        // custom jwt filter.
        http.addFilterBefore(jwtAuthFilter(), UsernamePasswordAuthenticationFilter.class);
    

【问题讨论】:

你有字符串安全吗? 【参考方案1】:

您可以按如下方式创建单独的 CORS 配置类。此类将处理整个应用程序中所有请求的 CORS 配置,您无需使用 @CrossOrigin 分别注释每个控制器。

@Configuration
public class CorsConfig 

    @Bean
    public CorsFilter corsFilter() 
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");         //'*' allows all endpoints, Provide your URL/endpoint, if any.
        config.addAllowedHeader("*");         
        config.addAllowedMethod("POST");   //add the methods you want to allow like 'GET', 'PUT',etc. using similar statements.
        config.addAllowedMethod("GET");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    

【讨论】:

我是否必须在某个地方调用该方法,还是因为它是 @Configuration ,所以它会自己做所有事情?因为我添加了课程但它不起作用:\ @Dseaster 您无需在任何地方调用该方法。它会自己做所有事情。 好的,但它不工作......不断给我错误。我已经复制了你的代码并添加了我需要的所有方法 @Dseaster 每个方法类型都在一个单独的语句中。我在答案中编辑了代码 sn-p。 是的,我是这样添加的【参考方案2】:

您可以通过覆盖addCorsMappingsWebMvcConfigurerAdapter 来添加它,因此要么创建一个扩展 WebMvcConfigurerAdapter 的类,要么在您的配置类中定义一个bean,如下所示:

    @Bean
    public WebMvcConfigurer corsConfigurer () 
        return new WebMvcConfigurerAdapter() 
            @Override
            public void addCorsMappings(CorsRegistry registry) 
                registry.addMapping("/api/**")
                        .allowedOrigins("http://domain1.com", "http://domain2.com")
                        .allowedMethods("GET", "OPTIONS")
                        .allowedHeaders("header1", "header2", "header3")
                        .exposedHeaders("header1", "header2")
                        .allowCredentials(false).maxAge(3600);
            
        
    

编辑

从 5.0 开始,WebMvcConfigurerAdapter 已弃用,因此您可以通过实现 WebMvcConfigurer 接口来实现相同的目标(添加了默认方法,感谢 java 8!并且可以直接实现而无需此适配器)

@Configuration
@EnableWebMvc
public class MyWebMvcConfig implements WebMvcConfigurer 

   @Override
   public void addCorsMappings(CorsRegistry registry) 
            registry.addMapping("/api/**")
                    .allowedOrigins("http://domain1.com", "http://domain2.com")
                    .allowedMethods("GET", "OPTIONS")
                    .allowedHeaders("header1", "header2", "header3")
                    .exposedHeaders("header1", "header2")
                    .allowCredentials(false).maxAge(3600);
   
 

【讨论】:

WebMvcConfigurerAdapter 已弃用 @Dseaster 谢谢你的回复,你可以看到我的编辑 您好,我已经尝试过您的新解决方案,但它不起作用。 allowedHeader和exposedHeaders是否需要指定? @Usr 你设法让它工作了吗?我在整个 Stack Overflow 和 Spring 文档中都没有解决同样的问题。【参考方案3】:

您可以添加一个全局配置,如

    @Bean
    public WebMvcConfigurer corsConfigurer() 
        return new WebMvcConfigurerAdapter() 
            @Override
            public void addCorsMappings(CorsRegistry registry) 
                registry.addMapping("/greeting-javaconfig").allowedOrigins("http://localhost:9000");
            
        ;
    

只需使用它来添加将影响所有端点的全局 corrs 配置。如果注释不起作用,请尝试此操作。

【讨论】:

以上是关于注释 CrossOrigin 在 Spring Boot 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot + Spring Data Rest Repositories 中使用 @CrossOrigin 注释的 CORS 问题

仅带有 POST 的 Spring Boot 和 @CrossOrigin 注释

在 Spring Boot 中使用 @CrossOrigin

Spring 的 ApplicationListener<AuthenticationSuccessEvent> 打破了@CrossOrigin

@CrossOrigin 不适用于 spring-boot-starter-web 2.5.2

在 Spring Boot 中使用 jwt 令牌的具有 http 安全性的 CrossOrigin