Spring Boot: проблема с CORS

Я использую Spring Boot версии 2.0.2Release. Ниже моя конфигурация безопасности

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
        prePostEnabled = true,
        securedEnabled = true,
        jsr250Enabled = true)
@ComponentScan("com.mk")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationProvider myAuthenticationProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.cors().configurationSource(corsConfigurationSource())
                .and()
                .csrf().disable()
                .anonymous().and()
                .authorizeRequests()
                .antMatchers(HttpMethod.GET,"/index.html").permitAll()
                .antMatchers(HttpMethod.POST,"/login").permitAll()
                .antMatchers(HttpMethod.GET,"*").authenticated()
                .and().httpBasic();
    }
    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

Я не могу вызвать какой-либо API (в том числе логин, который является permissionAll) из-за проблемы с CORS.

В браузере я получаю (он работает с Postman, так как проверка CORS там не выполняется)

Failed to load http://localhost:8080/myurl: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 403.

13
0
27 168
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Хотя безопасность Spring предоставляет способ настройки CORS в http configurer, существует гораздо более чистый подход для добавления фильтра CORS в приложение -

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyCORSFilter implements Filter {


@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");

    chain.doFilter(req, res);
}

@Override
public void init(FilterConfig filterConfig) {
}

@Override
public void destroy() {
}

}

Заказ фильтра с наивысшим приоритетом гарантирует, что MyCORSFilter реализация javax.servlet.Filter будет первой в цепочке. Надеюсь это поможет

Этот мне подходит. единственная проблема в том, что он вызывается несколько раз в одном запросе.

Mohit Kanwar 07.08.2018 09:22

Может случиться так, что он вызывается для каждого отдельного запроса, сделанного браузером, кроме вашего вызова api. Например, css, значки, изображения и т. д.

priteshbaviskar 07.08.2018 12:07

не css / icons и т. д., потому что они размещены на другом сервере, но позвольте мне проверить

Mohit Kanwar 07.08.2018 12:31

@MohitKanwar Попробуйте использовать OncePerRequestFilter, открытый класс CustomFIlter расширяет OncePerRequestFilter

G. Adnane 28.01.2019 21:13

У меня это не сработало, но сработало: stackoverflow.com/a/36821971/8092044

Tomas Lukac 29.08.2019 15:13

Итак, я понял, что он устарел. Если вы посмотрите на baeldung, он знает, как это сделать по-новому, так как они обновили webmvcconfigurer:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedMethods("*").allowedOrigins(frontDomain);
    }
}

Я не думаю, что вам не нужно использовать @EnableWebMvc. Если у вас есть это, весенняя загрузка не будет автоматически настраивать mvc.

Paulo van Goethe 07.08.2018 09:09

Кроме того, в чем смысл cors, если вы собираетесь разрешить все источники, о чем говорит ваш код.

Paulo van Goethe 07.08.2018 09:15

Вы правы относительно разрешения всех источников, это образец кода, который я использую для тестирования.

Mohit Kanwar 07.08.2018 09:18

Хорошо, я подумал, что что-то в этом роде происходит.

Paulo van Goethe 07.08.2018 09:30

Ознакомьтесь с этим руководством от Spring:

https://spring.io/guides/gs/rest-service-cors/

Есть несколько способов добавить поддержку CORS в Spring Boot.

Используя глобальную конфигурацию:

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

И используя аннотацию @CrossOrigin:

@CrossOrigin(origins = "http://localhost:9000")
@GetMapping("/greeting")
public Greeting greeting(@RequestParam(required=false, defaultValue = "World") String name) {
    System.out.println("==== in greeting === = ");
    return new Greeting(counter.incrementAndGet(), String.format(template, name));
}

Нет необходимости добавлять какие-либо дополнительные Filters или WebMvcConfigurer. Основная проблема заключается в том, что 'Access-Control-Allow-Origin' отсутствует в заголовке, поскольку corsConfigurationSource не добавляет необходимую конфигурацию для получения соответствующих заголовков ответов CORS. Следовательно, при настройке CorsConfigurationSource необходимо добавить следующие недостающие конфигурации.

configuration.addAllowedOrigin("*");
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");

Нам нужно настроить cors CorsConfigurationSource , как показано ниже.

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .cors().configurationSource(corsConfigurationSource())
                .and()
                 .....
  }

 @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        configuration.setAllowCredentials(true);
        //the below three lines will add the relevant CORS response headers
        configuration.addAllowedOrigin("*");
        configuration.addAllowedHeader("*");
        configuration.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

Если кто-то сталкивается с проблемой CORS с версиями Spring Boot 2.4.0 plus при наличии следующей комбинации, обратитесь к отвечать

CorsConfigurationSource#setAllowedOrigins value as *

а также

CorsConfigurationSource#setAllowCredentials value as true

Почему вы делаете addAllowedOrigin("*") после того, как у вас есть setAllowedOrigins(Arrays.asList("*"))?

GalAbra 12.04.2021 14:57

да, вы можете удалить следующий addAllowedOrigin("*"), поскольку мы уже добавили setAllowedOrigins(Arrays.asList("*")), я добавил, чтобы проиллюстрировать несколько вариантов, можно добавить источники

Prasanth Rajendran 12.04.2021 16:07

Но если вы удалите эти повторяющиеся строки, это будет тот же код, что и в вопросе OP, не так ли? Я не понимаю, у меня есть моя конфигурация, как вы сказали, но все же предварительная проверка имеет "No Allow Origin Header" ...

G-Unit 16.06.2021 20:19

Другие вопросы по теме