Подтвердить что ты не робот

Symfony2 за ELB перенаправляет на http вместо https

Вопрос:

  • Пользователь входит в систему с https://example.com/login
  • Аутентификация одобрена
  • Как настроено в security.yml Symfony2 перенаправляет пользователя на страницу профиля после входа в систему.
  • Но он перенаправляет их на неправильный URL http://example.com/homepage

security.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 и Server2 содержат приложение Symfony2.

Вопрос:

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

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

4b9b3361

Ответ 1

Взгляните на

поставщика/Symfony/Symfony/SRC/Symfony/Компонент/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

Ответ 2

  • Убедитесь, что параметры конфигурации trusted_hosts и trusted_proxies установлены соответствующим образом.
  • Убедитесь, что ваш балансировщик нагрузки добавляет X-Forwarded-For, X-Forwarded-Host, X-Forwarded-Port и, что самое главное, заголовки X-Forwarded-Proto для HTTP-запроса отправляют в приложение.

Документация: Доверенные прокси.


EDIT:

Как показано в @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');

Ответ 3

У меня была такая же проблема с приложением 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 как 'on', как обычно ожидалось, и разрешить Cake внутренне управлять протоколом в моей базовой константе URL.

Хорошо:

  • немедленно устранила проблему.
  • использовали 3 строки кода

Плохо:

  • всякий раз, когда я обновляю ядро ​​Cake, мне придется снова включить его.

Ответ 4

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

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

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

Приводятся примеры кодов

Ответ 5

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

Ответ 6

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

 RewriteCond %{HTTP:X-Forwarded-Proto} !https
 RewriteRule (.*) https://%{SERVER_NAME}/$1 [redirect=permanent,last]

Ответ 7

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