ELB 后面的 Symfony2 重定向到 http 而不是 https

Posted

技术标签:

【中文标题】ELB 后面的 Symfony2 重定向到 http 而不是 https【英文标题】:Symfony2 behind ELB is redirecting to http instead of https 【发布时间】:2014-06-30 12:35:22 【问题描述】:

问题:

用户使用https://example.com/login 登录 身份验证已获批准 根据 security.yml 中的配置,Symfony2 在登录后将用户重定向到个人资料页面。 但它会将他们重定向到错误的网址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

环境架构:

Server1 和 Server2 拥有 Symfony2 应用程序。

问题:

如何强制 Symfony 使用 https 协议而不是 http 生成重定向 URL?

到目前为止,我已经查看了这些文档,但解决方案在我的情况下不起作用:

http://symfony.com/doc/current/cookbook/routing/scheme.html

【问题讨论】:

你的routing.yml中有方案:[https]吗? 也试过了,谢谢回复。最初这会导致无限重定向,然后我将trusted_proxies:[10.0.0.0/8] 添加到config.yml 中。无限重定向现在消失了,但 Symfony 仍然生成重定向 URL 为 http 而不是 https。谢谢 我在 AWS 有这个确切的架构。不知道为什么你的不工作。如果用户只是点击example.com/login,他们是否会重定向到https 这也适用于下游部署在 Heroku 上的应用程序。 【参考方案1】:

上述解决方案对我不起作用。我将以下代码行(如 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 中的问题。

【讨论】:

Symony 文章提到“将您的 Web 服务器配置为不响应来自负载均衡器以外的任何客户端的流量。对于 AWS,这可以通过安全组来完成”。我的安全组设置为接受所有 HTTP 和 HTTPS 流量(即到 0.0.0.0/0)。我应该做一些不同的事情吗?注意:我有一些不想在 HTTPS 上提供服务的路由。谢谢!【参考方案2】:
    确保trusted_hoststrusted_proxies 配置属性设置正确。 确保您的负载均衡器将X-Forwarded-ForX-Forwarded-HostX-Forwarded-Port 以及最重要的X-Forwarded-Proto 标头添加到发送到应用程序的HTTP 请求中。

文档:Trusting Proxies。


编辑:

正如@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');

【讨论】:

我已将trusted_proxies 设置为[10.0.0.0/8],并且负载均衡器的标头可用并按建议设置。 Symfony 生成的重定向 URL 仍然是 http 而不是 https。谢谢 你能把var_dump($request->isSecure())的结果贴出来吗。 抱歉,错过了这个 Crozin。我会试试你的建议谢谢 只是给正在爬墙的其他人的注意事项 - 截至 16 年 4 月,ELB 似乎正在转发标准标题。至少使用 Elastic Beanstalk 和 PHP 5.6。 YMMV!【参考方案3】:

我已经在我的 .htaccess 中解决了这种问题,它的缺点是它总是重定向到 https 也不在 S2 防火墙后面,这在我的情况下是可以的,因为我只有公开可用的登录表单并且我想要要通过 https 发送的凭据

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

【讨论】:

【参考方案4】:

您是否使用绝对网址进行重定向?当我们在重定向中使用相对 url 时,我在 myracloud 背后遇到了类似的问题。 myracloud “修复”它并使其成为绝对,但丢失了协议。

【讨论】:

【参考方案5】:

我在 CakePHP 应用程序中使用 AWS 和带有 SSL 的 ELB 的 PHP 应用程序遇到了完全相同的问题。

我的解决方案在某些方面是好的,而在其他方面是坏的。问题在于 Amazon 发送的 HTTPS 标头与您查找的 PHP 标头不同:$_SERVER['HTTPS'] 已关闭,而 Amazon 发送的替代 HTTPS 标头可用于识别它实际上是在 HTTPS 下运行的:

$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'

我发现 Cake 内部定义的基本 URL 常量包含 http 协议,所以我只是在 Cake 中的 index.php 文件的第一行重新定义了 $_SERVER['HTTPS'] 变量 - 我不会如果你可以在 symfony 中做同样的事情,不要感到惊讶):

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') 
    $_SERVER['HTTPS'] = 'on';

这允许我的应用程序继续运行,检测 HTTPS 为正常预期的“开启”,并允许 Cake 在我的基本 URL 常量中内部管理协议。

好:

立即修复了问题 用了 3 行代码

不好:

每当我升级我的 Cake 核心时,我都必须重新安装它

【讨论】:

【参考方案6】:

看看

供应商/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

【讨论】:

天哪,错过了回答这个问题。我会试试你的建议谢谢 谢谢你——你会把覆盖代码放在 Symfony 的什么地方? 在生产中 - /web/app.php - 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】:

如何强制 Symfony 使用 https 协议而不是 http 生成重定向 URL?

您需要显式配置 HTTPS 协议,因为仅通过检测,Symfony2 只会猜测 HTTP,因为 HTTP 被用作应用程序的传输协议

所以对于创建重定向 URI 的组件,你需要注入 HTTPS 基础 URI-Scheme。一种简单的方法是将 base-URI 配置为参数,然后在配置中。

给出示例代码

点赞:http://web.archive.org/web/20130119123312/http://www.dobervich.com/2011/05/19/more-sophisticated-symfony2-login-redirection/ 或:http://web.archive.org/web/20130119124912/http://www.dobervich.com/2011/10/13/login-redirection-revisited/

【讨论】:

我遇到了同样的问题。如果我使用 HTTPS 向控制器发出请求,则 generateUrl() 使用 HTTP 的返回路径。

以上是关于ELB 后面的 Symfony2 重定向到 http 而不是 https的主要内容,如果未能解决你的问题,请参考以下文章

如何为 AWS Elb 后面的 reactJs SPA 重定向 http 到 https?

在 ELB 后面使用带有 Spring Boot 的 SAML 重定向到 http 而不是 https

在 AWS ELB 后面带有嵌入式 Undertow 的 Spring Boot - HTTP 到 HTTPS 重定向

在 AWS ELB 后面使用嵌入式 Tomcat 的 Spring Boot - HTTPS 重定向

ELB 可以根据 URL 重定向请求吗?

使用 IIS 在 ELB 上将 http 重定向到 https 的最佳方法