【问题标题】:Symfony2 - Access is denied (user is not fully authenticated)Symfony2 - 访问被拒绝(用户未完全通过身份验证)
【发布时间】:2014-07-14 18:07:41
【问题描述】:

我正在使用 Symfony2 开发一个网站,直到今天 - 登录没有问题。但现在登录时我没有正确验证 - Symfony 分析器将我列为logged in as: anon 而不是我登录的用户.我也被重定向回登录页面而不是目标路径。

登录过程由带有提交按钮的传统登录表单(即用户名 + 密码)组成。所有用户凭据都存储在 MySQL 中,并且我已将 User 实体设置为提供者。

我的 php 错误日志中没有错误,或者在 Symfony 分析器中的 Exception 或 Logs 下没有列出。

我的一个观察是会话属性标题下没有列出任何内容(在 Symfony 分析器 > 请求中) - 通常在成功登录后会列出一些安全上下文信息,但现在它总是空的。我尝试在主页上设置一个基本会话变量,该变量在设置时部分成功并显示在会话属性下,但每当尝试登录时都会被清除!

这是我的 security.yml 文件:

# app/config/security.yml

security:
  encoders:
    Woodcut\UserBundle\Entity\User: sha512

  role_hierarchy:
    ROLE_ADMIN:       ROLE_USER
    ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

  providers:
    main:
        entity: { class: Woodcut\UserBundle\Entity\User, property: username }

  firewalls:
    secured_area:
        pattern:   ^/
        anonymous: ~
        form_login:
            login_path: login
            check_path: login_check
            username_parameter: _username
            success_handler: custom_authentication_handler
            failure_handler: custom_authentication_handler
            #always_use_default_target_path: true
            #default_target_path: /login_router
        logout:
            path: /logout
            target: /
    dev:
        pattern:  ^/(_(profiler|wdt)|css|images|js)/
        security: false


  access_control:
    - { path: ^/admin, roles: ROLE_ADMIN }
    - { path: ^/ratings/update, roles: ROLE_USER }
    - { path: ^/ratings/new, roles: ROLE_USER }
    - { path: ^/favourite, roles: ROLE_USER }

我正在使用典型的 LAMP 堆栈在 Ubuntu 12.04 虚拟机上使用 Symfony 2.3.13 和 PHP 5.4.28 运行我的网站。 PHP 作为 mod_php 运行。

Symfony Profiler 的输出 > 调试:

INFO - Populated SecurityContext with an anonymous Token
DEBUG - Notified event "kernel.exception" to listener "Symfony\Component\Security\Http\Firewall  \ExceptionListener::onKernelException".
DEBUG - Access is denied (user is not fully authenticated) by "/vagrant_www/vprojects/woodcut/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AccessListener.php" at line 70; redirecting to authentication entry point
DEBUG - Calling Authentication entry point 

如果有人可以帮助我确定为什么用户被认证为匿名而不是他们自己,那就太好了。过去两天一直在努力寻找原因。

提前感谢您提供的任何帮助!

其他信息:我有一个运行网站副本的 VPS(用于客户预览)。我在本地 VM 上开发并 git push 我的更改,然后我通过 SSH 连接到我的 VPS 并执行 git pull 以保持我的两个版本同步。

奇怪的是 VPS 版本没有显示这个问题(即登录工作正常)但两个版本都使用相同的代码库,除了它们各自的 parameters.yml 和 parameters_dev.yml 文件中有一些细微差别.

更新:在对代码库进行大量编辑并在我的 VM 上执行 apt-get updateapt-get upgrade 后,问题开始出现。因此,为了隔离可能的原因,我回滚到较早的提交 - 看看问题是否与代码相关。但是尽管回滚到我的主要编码更改之前,问题仍然存在。

这让我想到原因可能不与代码相关,而可能与服务器相关,可能是通过 apt-get upgrade 安装的新版本 PHP (5.4.28) 中的某些东西,或者新的 php.ini 指令可能吗?

我已经运行了 Symfony 配置检查工具,一切似乎都很好!

很奇怪。

【问题讨论】:

  • 您在哪里(确切地说是 url)检查您的安全会话?请尝试在 /admin od /ratings/new 上检查它
  • 我猜是因为您没有为防火墙设置任何提供程序。在匿名 provider: main 之后添加这个
  • @PiotrPasich 我从 /admin 中检查了我的会话,在 Symfony Profiler 下 - 包含的会话属性:_security.secured_area.target_path "localhost:8888/vprojects/woodcut/web/app_dev.php/admin"。然后我被重定向回 /login。
  • @ElPoney 问题仍然存在。
  • 有人对此有任何想法吗?再次感谢!

标签: php mysql session symfony authentication


【解决方案1】:

我也在为同样的问题而苦苦挣扎。我检查了几乎所有内容,然后怀疑会话处理程序...

我有

session: ~

改为:

session:
    handler_id:  ~

有关会话处理的更多信息: http://symfony.com/doc/2.2/components/http_foundation/session_configuration.html#native-php-save-handlers

【讨论】:

  • 非常感谢,成功了!!但是,当我的 VPS 版本的站点不使用 handler_id: ~ 但它仍然有效时,这是如何工作的。也许有一些服务器设置会影响在 VPS 上设置的 Sessions(这意味着它不需要 handler_id 指令来工作)但在我的本地 VM 上没有。很奇怪,我真的很想从中学习,也许是时候再次查看有关会话的 Symfony 文档了。
  • 我没有时间检查它为什么会这样工作。无论如何,对于以前的配置,似乎使用了错误的处理程序。同时我会详细检查一下
  • 真是一种解脱。我花了半天时间才解决这个问题。我的 config.yml 将 handler_id 设置为 session.handler.native_file。我改成~。非常感谢!
【解决方案2】:

当 PHPSESSID cookie 随每个请求发生变化时,就会出现此问题。 如果这是您的情况,那么您应该检查这些请求之间的 PHPSESSID 响应 cookie,我敢打赌它们已更改。为什么会这样,这是真正的问题!

让我们暂时假设上述断言是正确的。

看到这个 cookie 一直在变化 Symfony/PHP 假设会话管理器实际上已经创建了一个新的用户会话,显然这需要用户重新验证(除非 RememberMe=true 不会导致登录页面重定向)。

例如,在开发环境中工作时,我对这个会话问题没有任何问题。但是,一旦我切换到 prod 环境 - 我的意思是 (1) 我刷新了 --env=prod 缓存然后 (2) 我加载了生产 /app.php 而不是 /app_dev.php 页面 - 它刚刚开始身份验证和请求成功后将我重定向到登录页面。

显然,起初我认为存在配置问题,也许我在这些环境中使用了一组不同的参数。但事实并非如此。所以肯定还有别的,但是什么?

我检查了 var/session/prod 目录并看到了许多 sess_xxx 文件。在 var/session/dev 目录中也是如此。显然那是不行的。所以我完全删除了 var/session/{prod,dev} 然后我重新加载了 /app.php 页面。这在 prod 和 dev 两种环境中都创建了 2-3 个 sess_xxx 文件。这是不好的。这表明某些东西以某种方式向 app_dev.php 发送请求,该请求将加载可能会自动注销您的开发环境(基于您的应用程序的安全/防火墙配置)。我打开了 app_dev.php 并添加了一个 exit(0),然后突然一切都开始运行良好。这就是正在发生的事情,不知何故这些环境混合在一起,对 prod 的调用最终会触发对 dev 的调用,这会立即让你注销。

为了快速修复,有些人只需将 framework::session::save_path 更改为 /tmp,这将由两个环境共享,因此您不会被注销,尽管您的应用程序仍会以某种方式发送对 app.php 和 app_dev.php 的请求,但由于他们使用相同的会话文件夹,他们认为会话是相同的(未更改)。所以一般来说,只要会话路径对所有环境都相同,这是一个快速修复。然而,这不是问题的解决方案!

另一个解决方法是不要同时使用 app_dev.php 和 app.php(反之亦然),我的意思是一次只使用一个文件/环境。这也是一个快速解决方案,而不是解决方案。

我所做的,但我仍然不明白发生了什么,是完全删除网络 {assetic,css,js,fonts}(或 bin/console assetic:dump --env=prod --no-debug)的东西,然后用 --env=prod 重新创建它们 - -无调试。这样就成功了,但我仍然不明白如何解决它。

我希望上述步骤可以帮助您比我更好地追踪问题的原因:-)

【讨论】:

  • 感谢您的回答,我可以追踪问题的原因。我意识到我在请求中定义了 2 个 PHPSESSID id。清除浏览器缓存解决了我的问题。
【解决方案3】:

我和你有同样的问题。

虽然@plewandowski 的回答解决了我的问题,但根本原因是PHP 配置中设置的session.save_path 是一个权限不正确的目录。

作为健全性检查,运行 php -i | grep session. 然后看看save_path的权限是否正确..

就我而言,session.save_path => /var/lib/php/sessions => /var/lib/php/sessions

检查权限

vagrant@vps:/var/www/site$ ls -lah /var/lib/php
total 16K
drwxr-xr-x  4 root root 4.0K Aug  5 18:01 .
drwxr-xr-x 56 root root 4.0K Aug  5 20:29 ..
drwxr-xr-x  6 root root 4.0K Aug  5 18:23 modules
drwx-wx-wt  2 root root 4.0K Jul 26 11:05 sessions

在这种情况下,运行 PHP 的用户 (www) 无法访问该目录并导致此问题。

sudo chmod 1777 /var/lib/php/sessions/修复

【讨论】:

    【解决方案4】:

    在 Symfony 4 中,我遇到了这个错误。

    在我的实体中,我没有用户名和密码,我必须添加它们。

    /** @see \Serializable::serialize() */
    public function serialize()
    {
        return serialize(array(
            $this->userId,
            $this->userUsername,
            $this->userPassword
            // see section on salt below
            // $this->salt,
        ));
    }
    
    /** @see \Serializable::unserialize() */
    public function unserialize($serialized)
    {
        list (
            $this->userId,
            $this->userUsername,
            $this->userPassword
            // see section on salt below
            // $this->salt
        ) = unserialize($serialized, array('allowed_classes' => false));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-15
      • 1970-01-01
      • 2017-11-28
      • 1970-01-01
      • 2019-12-12
      • 2018-01-06
      • 2018-04-25
      • 2018-06-24
      相关资源
      最近更新 更多