在我的Symfony2应用程序中,我设置了防火墙,以便/admin
路径下的所有内容都需要通过https运行,但是在部署时我得到一个重定向循环。我已经在防火墙上阅读了Symfony2站点上的文档,并设置了登录表单。我还阅读了一些Stack Overflow文章并尝试了他们的解决方案,但到目前为止还没有。
以下是我的配置,有什么我想念的吗?
(据我所知,服务器正在运行Apache,我无法从托管服务提供商直接访问服务器配置)
access_control:
# require ROLE_ADMIN for /admin*
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
- { path: ^/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
- { path: ^/admin*, roles: ROLE_ADMIN, requires_channel: https}
答案 0 :(得分:5)
更新:修复了此问题。事实证明,托管服务提供商没有设置一些服务器变量。
为了将来参考,请在web或public_html目录中的app.php
下添加以下内容。可能是一个肮脏的黑客,但它解决了我的问题。
if($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
{
$_SERVER['HTTPS'] = 'on';
$_SERVER['SERVER_PORT'] = 443;
}
答案 1 :(得分:2)
根据您自己的答案,您的网站似乎位于负载均衡器或反向代理之后(因为您需要检查HTTP_X_FORWARDED_PROTO
服务器变量,该变量通常为空。)
您的托管服务提供商可能在没有您明确知识的情况下进行了此类设置。默认情况下,除非X-Forwarded-Proto
文件中有add the proxy to a whitelist,否则Symfony会忽略X-Forwarded-For
和app/config/config.yml
标题:
framework:
trusted_proxies: [127.0.0.1, ::1]
127.0.0.1
和::1
应由您的托管服务提供商使用的实际代理/代理替换(他们应该能够告诉您)。
这样做可以让它在不破坏app.php文件的情况下工作。
答案 2 :(得分:2)
根据@Oldskool的正确答案,在SF> 3.3您可以使用env
变量在SF4中设置trusted_proxies
,为the node were removed since that version。
在Symfony> 3.2< 4 中,代码如下:
# web/app.php
// BEFORE
// ...
$kernel = new AppKernel('prod', false);
Request::setTrustedHeaderName(Request::HEADER_FORWARDED, null);
$request = Request::createFromGlobals();
// ...
// AFTER
// ...
$kernel = new AppKernel('prod', false);
Request::setTrustedHeaderName(Request::HEADER_FORWARDED, null);
Request::setTrustedProxies(['192.0.0.1', '10.0.0.0/8']);
$request = Request::createFromGlobals();
// ...
如果您使用的是SF4 ,则可以使用env
变量作为前端控制器(在public/index.php
中)读取它们。
因此,只需将env
变量TRUSTED_PROXIES
添加到所有可信代理中,用逗号“,”分隔:
TRUSTED_PROXIES = xxx.xxx.xxx.xxx/x,xxx.xxx.xxx.xxx/x,xxx.xxx.xxx.xxx/x
作为最终参考,您可以查看issue on GitHub about the infinite loop caused by forcing the https
。
ON HEROKU
作为一个简单的参考,因为我有Heroku的这个问题
如果您遇到麻烦forcing to https
并且您的应用程序位于Heroku上:
您必须遵循instructions provided by Heroku(仅适用于SF< = 3.2):
// web/app.php
Request::setTrustedProxies(array($request->server->get('REMOTE_ADDR')));
Request::setTrustedHeaderName(Request::HEADER_FORWARDED, null);
Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, null);
对于Symfony> 3.2(instructions here for SF4):
// SF >= 4: public/index.php
...
$kernel = new Kernel($env, $debug);
$request = Request::createFromGlobals();
// Add this
Request::setTrustedProxies(array($request->server->get('REMOTE_ADDR')), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
$response = $kernel->handle($request);
...