【问题标题】:Symfony2 http_basic security rejects valid credentialsSymfony2 http_basic 安全拒绝有效凭据
【发布时间】:2011-08-24 18:08:53
【问题描述】:

我使用 Symfony Standard 2.0.0BETA1 并尝试配置与 this book chapter 完全相同的 http_basic 身份验证

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. 输入有效凭据

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

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

【问题讨论】:

    标签: security symfony basic-authentication


    【解决方案1】:

    在Apache下使用PHP as cgi/fastCGI破坏http基本认证

    有一个解决方法:

    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 issue

    【讨论】:

      【解决方案2】:

      问题是您限制了对/.* 的访问,这意味着所有路径,仅限于具有角色 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 关于安全性的文档现在正在重写,并将详细讨论这个问题。它位于security 分支下的symfony-docs github 存储库中。

      问候, 马特

      【讨论】:

      • 好的,我明白你的意思,但我正在尝试使用 HTTP 基本,所以没有自定义登录表单,浏览器应该自动显示凭据表单(或者,按照标准,我可以通过简单地访问我的应用程序设置适当的标题,例如Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==)
      • +1 这让我发疯了,我使用的是 2.1,文档对此只字未提。
      【解决方案3】:

      在当前版本(Symfony 版本 2.1.8)中仍然存在同样的问题。

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

      至少,当前版本的修复比以前简单一点(与@Teo.sk 的答案相比),并且指令可以直接硬编码为框架的文件vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/ServerBag.php 中的 cmets:

      /*
      * 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]
      */
      

      简而言之,要修复它,您只需将以下行添加到应用程序的web/ 文件夹的.htaccess 文件中:

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

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

      RewriteEngine On
      

      【讨论】:

      • 这正是解决我的问题的原因。我已经在 stackoverflow 的其他地方找到了 RewriteRule,但它只有在我添加了 RewriteCond 之后才起作用。谢谢!
      • 这里是最短和最新的解决方案。
      【解决方案4】:

      您不需要修改您的 SymfonyProject,您还需要更改 apache2 配置。

      sudoedit /etc/apache2/sites-enabled/[你的站点].conf

      插入

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

      继续重启apache2

      享受:)

      【讨论】:

        【解决方案5】:

        我使用我的无限路线:

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

        没有最后一个斜线 错了

        /correspondencia/recepcion/
        

        不错

        /correspondencia/recepcion
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-10-28
          • 1970-01-01
          • 2018-02-23
          • 2015-05-27
          • 2021-09-16
          • 1970-01-01
          相关资源
          最近更新 更多