Symfony2 за ELB перенаправляет на http вместо https
Проблема:
- Пользователь входит в систему с помощью https://example.com/login
- Аутентификация одобрена
- Как настроено в security.yml Symfony2 перенаправляет пользователя на страницу профиля после входа в систему.
- Но он перенаправляет их на неправильный URL-адрес http://example.com/homepage
Безопасность.yml:
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
main:
pattern: ^/
form_login:
check_path: /login_check
login_path: /login
default_target_path: /profile
provider: fos_userbundle
logout:
path: /logout
target: /splash
anonymous: ~
access_control:
- { roles: ROLE_USER, requires_channel: https }
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
acl:
connection: default
Архитектура среды:
Сервер1 и Сервер2 содержат Symfony2 приложение.
Вопрос:
Как заставить Symfony генерировать URL-адрес перенаправления по протоколу https вместо http?
До сих пор я просматривал эти документы, и решение не сработало в моем случае:
7 answers
Взгляните на
Vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Request.php
AWS ELB использует HTTP_X_FORWARDED_PROTO и HTTP_X_FORWARDED_PORT, в то время как Symfony просматривает заголовки X_FORWARDED_PROTO и X_FORWARDED_PORT, чтобы оценить соединение и его безопасный статус.
Вы можете попробовать изменить эти ключи в trustedHeaders, хотя я бы не рекомендовал напрямую изменять их, но найти способ переопределить их.
protected static $trustedHeaders = array(
self::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',
self::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST',
self::HEADER_CLIENT_PROTO => 'HTTP_X_FORWARDED_PROTO',
self::HEADER_CLIENT_PORT => 'HTTP_X_FORWARDED_PORT',
);
- Убедитесь, что свойства конфигурации
trusted_hosts
иtrusted_proxies
установлены соответствующим образом. - Убедитесь, что ваш балансировщик нагрузки добавляет
X-Forwarded-For
,X-Forwarded-Host
,X-Forwarded-Port
и, что самое важное,X-Forwarded-Proto
заголовки HTTP-запроса отправляются в приложение.
Документация: Доверительные доверенные лица.
ИЗМЕНИТЬ:
Как предложил @A23, вам также следует проверить, использует ли ELB "стандартные" имена заголовков. Если нет, измените их, используя одно из следующих:
Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X-Proxy-For');
Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X-Proxy-Host');
Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X-Proxy-Port');
Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X-Proxy-Proto');
У меня была точно такая же проблема с PHP-приложением, использующим AWS и ELB с SSL в приложении CakePHP.
Мое решение было хорошим в некоторых отношениях и плохим в других. Проблема заключалась в том, что Amazon отправляет заголовки HTTPS, отличные от заголовков PHP, которые вы ищете: $_SERVER['HTTPS']
отключен, в то время как Amazon отправляет альтернативные заголовки HTTPS, которые вы можете использовать, чтобы определить, что он на самом деле работает под HTTPS:
$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'
Я выяснил, что моя базовая константа URL, которую Cake определил внутренне, имела http
протокол в нем, поэтому я просто переопределил переменную $_SERVER['HTTPS']
в самой первой строке моего файла index.php
в Cake - и я не удивлюсь, если вы сможете сделать то же самое в symfony):
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
Это позволило моему приложению продолжить работу, определить HTTPS как "включенный", как обычно и следовало ожидать, и позволить Cake внутренне управлять протоколом в моей базовой константе URL.
Хорошо:
- немедленно исправлена проблема
- использовал 3 строки код
Плохо:
- всякий раз, когда я обновляю ядро своего торта, мне придется снова вставлять его обратно
Как заставить Symfony генерировать URL-адрес перенаправления по протоколу https вместо http?
Вам необходимо явно настроить протокол HTTPS, потому что только при обнаружении Symfony2 будет только угадывать HTTP, поскольку HTTP используется в качестве транспортного протокола для приложения.
Таким образом, для компонента, который создает URI перенаправления, вам необходимо ввести базовую схему URI HTTPS. Один простой способ сделать это - настроить базовый URI в качестве параметра, а затем в конфигурация.
Приведены примеры кодов
Используете ли вы абсолютный URL-адрес для перенаправления? я столкнулся с аналогичной проблемой за myracloud, когда мы использовали относительные URL-адреса при перенаправлении. myracloud "исправил" его и сделал абсолютным, но потерял протокол.
Я решил такого рода проблему в своем.htaccess, у него есть недостаток в том, что он всегда перенаправляет на https, а также не за брандмауэром S2, что в моем случае нормально, так как у меня есть только общедоступная форма входа, и я хочу, чтобы учетные данные отправлялись по https
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{SERVER_NAME}/$1 [redirect=permanent,last]
Приведенные выше решения не сработали для меня. Я добавил следующую строку кода (как предложено в документах Symfony2 http://symfony.com/doc/current/cookbook/request/load_balancer_reverse_proxy.html#but-what-if-the-ip-of-my-reverse-proxy-changes-constantly ) к моему web/app.php
:
Request::setTrustedProxies(array($request->server->get('REMOTE_ADDR')));
Сразу после
$request = Request::createFromGlobals();
Это решило для меня проблему в Symfony 2.5.