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

Архитектура среды:

enter image description here

Сервер1 и Сервер2 содержат Symfony2 приложение.

Вопрос:

Как заставить Symfony генерировать URL-адрес перенаправления по протоколу https вместо http?

До сих пор я просматривал эти документы, и решение не сработало в моем случае:

Author: TeaCupApp, 2014-05-13

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',
    );

Ссылка - http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/TerminologyandKeyConcepts.html#x-forwarded-for

 20
Author: A23, 2014-05-21 03:48:20
  1. Убедитесь, что свойства конфигурации trusted_hosts и trusted_proxies установлены соответствующим образом.
  2. Убедитесь, что ваш балансировщик нагрузки добавляет 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');
 7
Author: Crozin, 2014-05-22 16:41:39

У меня была точно такая же проблема с 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 строки код

Плохо:

  • всякий раз, когда я обновляю ядро своего торта, мне придется снова вставлять его обратно
 2
Author: Robbie Averill, 2014-05-21 04:03:12

Как заставить Symfony генерировать URL-адрес перенаправления по протоколу https вместо http?

Вам необходимо явно настроить протокол HTTPS, потому что только при обнаружении Symfony2 будет только угадывать HTTP, поскольку HTTP используется в качестве транспортного протокола для приложения.

Таким образом, для компонента, который создает URI перенаправления, вам необходимо ввести базовую схему URI HTTPS. Один простой способ сделать это - настроить базовый URI в качестве параметра, а затем в конфигурация.

Приведены примеры кодов

 0
Author: hakre, 2014-05-18 15:36:02

Используете ли вы абсолютный URL-адрес для перенаправления? я столкнулся с аналогичной проблемой за myracloud, когда мы использовали относительные URL-адреса при перенаправлении. myracloud "исправил" его и сделал абсолютным, но потерял протокол.

 0
Author: oliver nadj, 2014-05-22 10:24:11

Я решил такого рода проблему в своем.htaccess, у него есть недостаток в том, что он всегда перенаправляет на https, а также не за брандмауэром S2, что в моем случае нормально, так как у меня есть только общедоступная форма входа, и я хочу, чтобы учетные данные отправлялись по https

 RewriteCond %{HTTP:X-Forwarded-Proto} !https
 RewriteRule (.*) https://%{SERVER_NAME}/$1 [redirect=permanent,last]
 0
Author: m0c, 2014-05-22 10:36:59

Приведенные выше решения не сработали для меня. Я добавил следующую строку кода (как предложено в документах 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.

 0
Author: totas, 2015-03-01 12:54:02