Symfony2 http_basic 安全性拒绝有效凭据

发布于 2024-11-07 03:55:14 字数 953 浏览 0 评论 0原文

我使用 Symfony Standard 2.0.0BETA1 并尝试配置与 本书章节

security:
encoders:
    Symfony\Component\Security\Core\User\User: plaintext

providers:
    main:
        users:
            foo: { password: testing, roles: ROLE_USER }

firewalls:
    main:
        pattern:    /.*
        http_basic: true
        logout:     true

access_control:
    - { path: /.*, role: ROLE_USER }

问题是,当我尝试打开一个页面并提交用户名“foo”和密码“testing”时,它只是循环并无限地要求我提供凭据或显示错误页面。

重现问题的步骤:

  1. http://symfony.com 复制安全配置/doc/current/book/security/overview.html#configuration 并将其粘贴到 security.yml 文件
  2. 刷新应用程序主页
  3. 输入有效凭据

预期行为是查看主页,但显示凭据提示。

有谁知道为什么会发生这种情况以及如何解决它?

I use Symfony Standard 2.0.0BETA1 and tried to configure http_basic authentication exactly the same as in this book chapter

security:
encoders:
    Symfony\Component\Security\Core\User\User: plaintext

providers:
    main:
        users:
            foo: { password: testing, roles: ROLE_USER }

firewalls:
    main:
        pattern:    /.*
        http_basic: true
        logout:     true

access_control:
    - { path: /.*, role: ROLE_USER }

Problem is when I try to open a page and i submit user name "foo" and password "testing" it simply loops and ask me for credential infinitely or display error page.

Steps to reproduce issue:

  1. Copy security configuration from http://symfony.com/doc/current/book/security/overview.html#configuration and past it to security.yml file
  2. Refresh app home page
  3. Enter valid credentials

Expected behavior is to see home page but instead credentials prompt is shown.

Does anyone know why that happens and how to fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

全部不再 2024-11-14 03:55:14

http 基本身份验证在 Apache 下使用 PHP 作为 cgi/fastCGI 被破坏

有一个解决方法:

app_dev.php

if( !isset($_SERVER['PHP_AUTH_USER']) )
{
    if (isset($_SERVER['HTTP_AUTHORIZATION']) && (strlen($_SERVER['HTTP_AUTHORIZATION']) > 0))
    {
        list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
        if( strlen($_SERVER['PHP_AUTH_USER']) == 0 || strlen($_SERVER['PHP_AUTH_PW']) == 0 )
        {
            unset($_SERVER['PHP_AUTH_USER']);
            unset($_SERVER['PHP_AUTH_PW']);
        }
    }
}

web/.htaccess

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] 
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ app.php [QSA,L]
</IfModule>

来源:symfony github问题

The http basic authentication is broken with PHP as cgi/fastCGI under Apache

There is a workaround:

app_dev.php

if( !isset($_SERVER['PHP_AUTH_USER']) )
{
    if (isset($_SERVER['HTTP_AUTHORIZATION']) && (strlen($_SERVER['HTTP_AUTHORIZATION']) > 0))
    {
        list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
        if( strlen($_SERVER['PHP_AUTH_USER']) == 0 || strlen($_SERVER['PHP_AUTH_PW']) == 0 )
        {
            unset($_SERVER['PHP_AUTH_USER']);
            unset($_SERVER['PHP_AUTH_PW']);
        }
    }
}

web/.htaccess

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] 
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ app.php [QSA,L]
</IfModule>

Source: symfony github issue

心是晴朗的。 2024-11-14 03:55:14

问题是您将对 /.*(这意味着所有路径)的访问权限限制为仅限具有 ROLE_USER 角色的用户。

假设您的登录路径是 /login,用户尝试访问任何其他路径并被重定向到登录路径。登录路径 (/login) 将与访问控制模式 /.* 匹配。然后,该用户将被拒绝访问,因为他现在不具有 ROLE_USER 角色。安全组件将再次将用户重定向到登录表单,以便他可以进行身份​​验证以获取受限制的角色,并将用户重定向到登录表单进行身份验证等等。

这是避免此问题的简单解决方案。您可以通过激活匿名用户配置和新的访问控制项来允许匿名用户访问登录表单。在firewalls配置中的main下方添加以启用匿名用户:

security:
    firewalls:
        main:
            anonymous: true

并添加新的访问控制项以允许匿名用户访问/login模式:

access_control:
    - { path: /login, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: /.*, role: ROLE_USER }

这里的顺序很重要,因为规则是:第一个匹配的路径获胜。因此,/login 路径必须位于其他路径 /.* 的模式之上。这应该可以解决您的重定向循环问题。

Symfony 关于安全性的文档现在正在重写,并将更详细地讨论这个问题。它位于 symfony-docs github 存储库中 安全 分支。

问候,
马特

The problem is you restricted access to /.*, which means all paths, to only users who have the role ROLE_USER.

Say your login path is /login, the user tries to access any other path and is redirected to the login path. The login path (/login) will be matched by the access control pattern /.*. The user will then be denied of access because he doesn't have the role ROLE_USER right now. The security component will redirect the user again to the login form so he can authenticate to get the role, which is restricted, and will redirect the user to the login form to authenticate and so on.

Here's a simple solution to avoid this problem. You can allow access to the login form to anonymous user with the activation of the anonymous user configuration and a new access control item. Add this below main in the firewalls configuration to enable anonymous user:

security:
    firewalls:
        main:
            anonymous: true

And add a new access control item to allow anonymous user to acces the /login pattern:

access_control:
    - { path: /login, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: /.*, role: ROLE_USER }

The order is important here since the rule is: first path matched wins. So the /login path must be above your pattern for other path /.*. This should resolves you redirect loop.

The documentation of Symfony about security is being rewritten right now and will talk more in details about this problem. It is in the symfony-docs github repository under the security branch.

Regards,
Matt

定格我的天空 2024-11-14 03:55:14

当前版本(Symfony 版本 2.1.8)仍然出现同样的问题。

这是因为 Apache + PHP 作为 FastCGI 处理 HTTP 身份验证变量的特殊方式。

至少,当前版本的修复比以前更简单(与@Teo.sk的答案相比),并且这些说明可以直接硬编码为文件中的注释 vendor/symfony/symfony/src框架的 /Symfony/Component/HttpFoundation/ServerBag.php

/*
* php-cgi under Apache does not pass HTTP Basic user/pass to PHP by default
* For this workaround to work, add these lines to your .htaccess file:
* RewriteCond %{HTTP:Authorization} ^(.+)$
* RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
*
* A sample .htaccess file:
* RewriteEngine On
* RewriteCond %{HTTP:Authorization} ^(.+)$
* RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
* RewriteCond %{REQUEST_FILENAME} !-f
* RewriteRule ^(.*)$ app.php [QSA,L]
*/

简而言之,要修复它,您所要做的就是将以下行添加到框架的 .htaccess 文件中应用程序的 web/ 文件夹:

RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

新信息 (2013-05-01):现在我使用的是 Symfony 版本 2.2.1,为了使修复生效,我必须将这两行代码添加到以下 web/.htaccess 行的正下方:

RewriteEngine On

The same problem still occurs in the current version (Symfony version 2.1.8).

It's because of the special way that Apache + PHP as FastCGI handles HTTP auth variables.

At least, the fix for the current version is a little simplier than it was before (as compared to @Teo.sk's answer), and the instructions are available directly hardcoded as comments in the file vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/ServerBag.php of the framework:

/*
* php-cgi under Apache does not pass HTTP Basic user/pass to PHP by default
* For this workaround to work, add these lines to your .htaccess file:
* RewriteCond %{HTTP:Authorization} ^(.+)$
* RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
*
* A sample .htaccess file:
* RewriteEngine On
* RewriteCond %{HTTP:Authorization} ^(.+)$
* RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
* RewriteCond %{REQUEST_FILENAME} !-f
* RewriteRule ^(.*)$ app.php [QSA,L]
*/

In short, to fix it, all you have to do is to add the following lines to the .htaccess file of the web/ folder of your application:

RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

New info (2013-05-01): now I'm using Symfony version 2.2.1 and for the fix to work I had to add those two lines of codes right below the following line of web/.htaccess:

RewriteEngine On
与风相奔跑 2024-11-14 03:55:14

你不需要修改你的SymfonyProject,你还需要改变apache2配置。

sudoedit /etc/apache2/sites-enabled/[your site].conf

插入

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] 
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app.php [QSA,L]

保持重新启动 apache2

享受:)

you dont't need to modify your SymfonyProject, you need also change apache2 configuration.

sudoedit /etc/apache2/sites-enabled/[your site].conf

insert

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] 
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app.php [QSA,L]

keep to restart apache2

enjoy :)

不醒的梦 2024-11-14 03:55:14

我使用我的边界路线:

 - { path: /correspondencia/recepcion/login, role: IS_AUTHENTICATED_ANONYMOUSLY }
 - { path: /correspondencia/recepcion, role: ROLE_ADMIN }

没有最后一个斜杠
错误的

/correspondencia/recepcion/

/correspondencia/recepcion

i use my boundle route:

 - { path: /correspondencia/recepcion/login, role: IS_AUTHENTICATED_ANONYMOUSLY }
 - { path: /correspondencia/recepcion, role: ROLE_ADMIN }

without the last slash
wrong

/correspondencia/recepcion/

good

/correspondencia/recepcion
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文