httpd дублирует Access-Control-Allow-Origin с всегда установленным заголовком

Я пытаюсь включить CORS на своем сервере. Он содержит как Apache HTTPD, так и Apache Tomee. HTTPD настроен как:

SetEnvIf Origin "^https://(.+\.)?my-domain.com$" allowed_origin=$0
Header always set Access-Control-Allow-Origin %{allowed_origin}e env=allowed_origin
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS, HEAD, PUT, DELETE, PATCH"
Header set Access-Control-Allow-Headers "accept,x-requested-method,origin,x-requested-with,x-request,cache-control,content-type"
Header set Access-Control-Max-Age "600"

и мой веб-XML Tomee:

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Accept-Language,Keep-Alive</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT,PATCH,DELETE</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Моя проблема в том, что я дважды получаю заголовок Access-Control-Allow-Credentials в ответ на предварительный запрос OPTIONS:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://my-origin.my-domain.com
Access-Control-Allow-Origin: https://my-origin.my-domain.com
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 600
Access-Control-Allow-Methods: GET, POST, OPTIONS, HEAD, PUT, DELETE, PATCH
Access-Control-Allow-Headers: accept,x-requested-method,origin,x-requested-with,x-request,cache-control,content-type,authorization

Я не понимаю, почему использование ключевого слова set в моей конфигурации HTTPD не удаляет дубликат Access-Control-Allow-Origin. Более того, если я удалю ключевое слово «всегда», он вернет только один Access-Control-Allow-Origin...


person Guillaume    schedule 27.06.2016    source источник
comment
Я бы сделал дамп tcp между httpd и посмотрел, где добавляются дополнительные заголовки.   -  person Jonathan S. Fisher    schedule 28.06.2016
comment
У меня похожая проблема, но удаление ключевого слова always не решает ее, запросы по-прежнему содержат повторяющиеся заголовки. Апач 2.4.25   -  person GraduateOfAcmeU    schedule 20.01.2017


Ответы (2)


Испытывает аналогичную проблему. Много времени потратил на отладку.

Это ошибка в Apache. Нарушение внутреннего дизайна и отсутствие документального подтверждения.

Header [table] set [cookie] [value] [...]

Это команда для управления заголовками. В apache есть как минимум две таблицы cookie.

  • onsuccess, по умолчанию, используется для кодов состояния 20X.
  • always, используется для ошибок, включая коды редиректов.

Судя по моему опыту в дикой природе, к ответу добавляются все куки со всех таблиц.

В вашем примере файл cookie, установленный Tomcat, находится в таблице onsuccess, наборы файлов cookie в apache находятся в таблице всегда. Ответ получает оба файла cookie, следовательно, дублирование.

Это становится более грязным, чем это. Таблицы имеют разное значение в зависимости от того, какие модули используются. Например, при использовании прокси-сервера или CGI соответствующей таблицей для файлов cookie является onsuccess, если вышестоящий сервер доставляет ошибку успешно, и always, если возникает внутренняя ошибка apache.

Это поведение не задокументировано. Это кажется не преднамеренным, а следствием внутренностей apache. В текущем состоянии практически невозможно правильно манипулировать заголовками с помощью Apache.

person user5994461    schedule 23.06.2017
comment
bz.apache.org/bugzilla/show_bug.cgi?id=61860 обсуждает именно эту проблему и содержит патч (уже слитый в транк). - person knoepfchendruecker; 20.08.2018
comment
Большое спасибо .... Идеальный ответ. Я нашел эту проблему, и только этот ответ решает мою проблему. - person ChelloFera; 09.03.2020

Принятый ответ правильный. Это просто способ справиться с этим, который я использовал.

SetEnvIf Origin "^(.*(\.yoursite.com)[:0-9]*)$" cors=$1
# wash out these headers in the 'onsuccess' table if we get them from the backend
Header onsuccess unset Access-Control-Allow-Origin env=cors
Header onsuccess unset Access-Control-Allow-Credentials env=cors
Header onsuccess unset Access-Control-Allow-Methods env=cors
Header onsuccess unset Access-Control-Allow-Headers env=cors
# add them to the 'always' table
Header always set Access-Control-Allow-Origin %{cors}e env=cors
Header always set Access-Control-Allow-Credentials "true" env=cors
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, PUT, DELETE" env=cors
Header always set Access-Control-Allow-Headers "accept,x-requested-method,origin" env=cors
person Andreas Wederbrand    schedule 17.05.2018