2016-11-30 2 views
0

Так я настроил приложение загрузки весной и настроить CORS фильтрусловия Same-происхождения в Spring MVC

@Bean 
public CorsFilter corsFilter() { 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
    CorsConfiguration config = new CorsConfiguration(); 
    config.addAllowedOrigin("*"); 
    config.addAllowedHeader("*"); 
    config.addAllowedMethod("GET"); 
    config.addAllowedMethod("POST"); 
    config.addAllowedMethod("PUT"); 
    config.addAllowedMethod("DELETE"); 
    config.addAllowedMethod("OPTIONS"); 
    source.registerCorsConfiguration("/**", config); 
    return new CorsFilter(source); 
} 

Для взаимодействия с задним концом я настроил Amazon Api шлюз и я настроил пользовательский доменное имя для Api шлюза по протоколу HTTPS : // api.mydomain.com. Использование сайта https: // api.mydomain.com для взаимодействия с моим задним концом. Сайт и back-end (Api), расположенные на одном сервере. test.mydomain.com (site) и test.mydomain.com:7000 (api)

Когда я отправил запрос с сайта на задний план через ApiGateway, я не получил требуемый ответ для CORS для проверки заголовков : Access-Control-Allow-Origin Access-Control-Allow-Methods Access-Control-Allow-Headers Я получил ответ без этого заголовка. Во время расследования и отладки я обнаружил, что в org.springframework.web.cors.DefaultCorsProcessor мой запрос определяется как запрос с одним источником.

org.springframework.web.util.WebUtils 

    /** 
     * Check if the request is a same-origin one, based on {@code Origin}, {@code Host}, 
     * {@code Forwarded} and {@code X-Forwarded-Host} headers. 
     * @return {@code true} if the request is a same-origin one, {@code false} in case 
     * of cross-origin request. 
     * @since 4.2 
     */ 
     public static boolean isSameOrigin(HttpRequest request) { 
      String origin = request.getHeaders().getOrigin(); 
      if (origin == null) { 
       return true; 
      } 
      UriComponentsBuilder urlBuilder; 
      if (request instanceof ServletServerHttpRequest) { 
       // Build more efficiently if we can: we only need scheme, host, port for origin comparison 
       HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest(); 
       urlBuilder = new UriComponentsBuilder(). 
         scheme(servletRequest.getScheme()). 
         host(servletRequest.getServerName()). 
         port(servletRequest.getServerPort()). 
         adaptFromForwardedHeaders(request.getHeaders()); 
      } 
      else { 
       urlBuilder = UriComponentsBuilder.fromHttpRequest(request); 
      } 
      UriComponents actualUrl = urlBuilder.build(); 
      UriComponents originUrl = UriComponentsBuilder.fromOriginHeader(origin).build(); 
      return (actualUrl.getHost().equals(originUrl.getHost()) && getPort(actualUrl) == getPort(originUrl)); 
     } 

Это условие пропускает добавление заголовка CORS к ответу. заголовки из запроса:

Origin=https://test.mydomain.com 
Host=test.mydomain.com:7000 
X-Forwarded-Port=443 (this header added by Api Gateway) 
X-Forwarded-Proto=https (this header added by Api Gateway) 

Метод isSameOrigin сравнить actualUrl и originUrl. Для кондиционирования мяса этот Url должен быть абсолютно одинаковым (протокол, хост и порт). OriginUrl - это URL-адрес на основе заголовка Origin https: // test.mydomain.com. ActualUrl - это URL-адрес, основанный на заголовке узла с применяемыми значениями из заголовков «Переадресованные». Test.mydomain.com:7000 → (применить X-Forwarded-Port) test.mydomain.com:443 → (применить x-forwarded-proto) https:// test.mydomain.com:443. Из-за этого OriginUrl https: // test.mydomain.com:443 (443 - порт для https) равны ActualUrl https: // test.mydomain.com:443.

Как я понимаю, заголовок Host - это заголовок, который содержит путь к конечной точке. Заголовки запросов X-Forwarded-Proto/X-Forwarded-Port помогают идентифицировать протокол (HTTP или HTTPS) и порт, который клиент использовал для подключения к прокси. Но почему метод isSameOrigin адаптирует X-Forwarded-Proto/X-Forwarded-Port к значению хоста, не ясен, потому что происхождение этих переадресованных и хост-заголовков отличается.

Не могли бы вы пояснить, почему Spring filter идентифицирует мой запрос как Same-Origin, в частности, почему он использует метод adaptFromForwardedHeaders (request.getHeaders()). Я попытался найти причины в совершении, но нет объяснений https://github.com/spring-projects/spring-framework/commit/9a52c8144313a5093bf6b7153cd89857aaed1899#diff-82a2156da5855b577acb70b86fade1ca.

Возможно, Amazon ApiGateway пропускает/игнорирует заголовок X-Forwarded-Host для идентификации хоста, который клиент использует для подключения к прокси.

BTW: когда я использую свою конечную точку напрямую (без использования прокси-сервера Api Gateway), все работает нормально, и моя конечная точка возвращает заголовки Access-Control-Allow.

ответ

0

Вы правы, что API-шлюз не будет использовать X-Forwarded-Host для идентификации хоста.

 Смежные вопросы

  • Нет связанных вопросов^_^