Так я настроил приложение загрузки весной и настроить 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.