Проблема конфигурации CORS Spring Boot - Access-Control-Request-Method: POST - PullRequest
0 голосов
/ 02 января 2019

У меня есть конфигурация CORS:

  @Bean
  CorsConfigurationSource corsConfigurationSource() {
    LOGGER.info("Configuring CORS");
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000", "https://localhost:3000", "http://localhost:2199", "https://localhost:2199"));
    configuration.setAllowCredentials(true);
    configuration.setAllowedHeaders(
        Arrays.asList("Access-Control-Allow-Headers",
            "Access-Control-Allow-Origin", "Access-Control-Request-Method",
            "Access-Control-Request-Headers", "Origin", "Cache-Control",
            "Content-Type", "Authorization", "Accept"));
    configuration.setAllowedMethods(
        Arrays.asList("DELETE", "GET", "POST", "PATCH", "PUT"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
  }

Это работает для этого запроса:

curl -v -XOPTIONS -H 'Access-Control-Request-Headers: content-type' -H 'Origin: http://localhost:3001' http://localhost:8080/auth/create-account

Возвращает 200

Не работает, если я добавлю Access-Control-Request-Method: POST

curl -v -XOPTIONS -H 'Access-Control-Request-Headers: content-type' -H 'Origin: http://localhost:3001' http://localhost:8080/auth/create-account -H 'Access-Control-Request-Method: POST'

Вот контроллер:

@RestController
@RequestMapping("/auth")
public class AuthEndpoint {

@PostMapping("/login")
  public ResponseEntity<Object> doLogin(@RequestBody @Valid LoginDTO loginDTO) {
    LOGGER.debug("Attempting login {}", loginDTO);
    try {
    .....

В журнале Spring написано:

2019-01-01 21:16:35.100 DEBUG 24848 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : OPTIONS "/auth/create-account", parameters={}
2019-01-01 21:16:35.104 DEBUG 24848 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.http.ResponseEntity<java.lang.Object> rest.AuthEndpoint.createAccount(NewAccountDTO)
2019-01-01 21:16:35.106 DEBUG 24848 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2019-01-01 21:16:35.112 DEBUG 24848 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2019-01-01 21:16:35.112 DEBUG 24848 --- [nio-8080-exec-1] o.s.orm.jpa.EntityManagerFactoryUtils    : Closing JPA EntityManager
2019-01-01 21:16:35.112 DEBUG 24848 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed 403 FORBIDDEN

Похоже, что сервлет-диспетчер перехватывает и убивает его, но только с заголовком Access-Control-Request-Method, без этого заголовка он работает.

Теперь, если я поменяю контроллер для добавления этого: @CrossOrigin(origins = "http://localhost:3000") работают оба пути.

У меня вопрос, как мне глобально настроить все мое приложение, чтобы избежать необходимости украшать каждый контроллер REST (что должно быть избыточным) @CrossOrigin аннотацией?

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Глобальная конфигурация CORS Spring MVC описана в этом блоге , который я написал, и в справочной документации Spring Framework .

Spring Security автоматически обнаружит Spring MVC CORSконфигурации и использовать ее для авторизации запросов, если вы включили поддержку CORS на уровне Spring Security .

0 голосов
/ 02 января 2019

Добавьте «Опции» в разрешенном методе

  response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, PUT, PATCH, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Authorization, User-Accept-Language");
    if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
    } else {
            chain.doFilter(req, res);
    }
...