Annotation CrossOrigin not working in Spring boot

折月煮酒 提交于 2019-12-08 05:09:43

问题


I have a Spring Boot application that exposes some endpoints. From a React app I want to make requests to these endpoints, but it keeps giving me CORS problem:

access to XMLHttpRequest at 'localhost:9090/helios-admin/api/dashboard/clients?page=0&size=30' from origin 'http://localhost:3000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

So I've tried using @CrossOrigin annotation for all my methods and also for the Controller class, but the error is the same.
The get request in my react app looks like this:

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);
        })
    }

What's missing?

EDIT In my spring boot app I have only this class to configure security:

@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:


You can add it by overriding addCorsMappings of WebMvcConfigurerAdapter, so either create a class that extends WebMvcConfigurerAdapter or define a bean in your configuration class like this:

    @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);
            }
        }
    }

Edit

As of 5.0 WebMvcConfigurerAdapter is deprecated and hence you could acheive the same thing by implementing WebMvcConfigurer interface (added default methods, thanks java 8 ! and can be implemented directly without the need for this adapter)

@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);
   }
 }



回答2:


You can create separate CORS configuration class as follows. This class will handle the CORS configurations for all requests throughout your application and you need not annotate each controller separately with @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);
    }
}



回答3:


You can add a global configuration like

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

Just use this to add a global corrs configuration that will affect all the endpoints.Try this if the annotation doesn't work.



来源:https://stackoverflow.com/questions/55904200/annotation-crossorigin-not-working-in-spring-boot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!