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

问题:

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?

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

【问题讨论】:

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

标签: php .htaccess symfony redirect amazon-elb


【解决方案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】:
  1. 确保trusted_hoststrusted_proxies 配置属性设置正确。
  2. 确保您的负载均衡器将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 配置为参数,然后在配置中。

        给出示例代码

        【讨论】:

        • 我遇到了同样的问题。如果我使用 HTTPS 向控制器发出请求,则 generateUrl() 使用 HTTP 的返回路径。
        猜你喜欢
        • 2019-04-21
        • 1970-01-01
        • 2018-01-12
        • 2018-09-26
        • 2018-08-18
        • 2017-05-15
        • 2019-07-12
        • 1970-01-01
        • 2021-12-12
        相关资源
        最近更新 更多