Symfony2 - 拒绝访问(用户未完全通过身份验证)

时间:2014-05-26 03:02:58

标签: php mysql session symfony authentication

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

登录过程包含传统的登录表单(即用户名+密码)和提交按钮。所有用户凭据都存储在MySQL中,我将用户实体设置为提供者。

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

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

这是我的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(用于客户端预览)。我开发了我的本地虚拟机并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配置检查工具,一切看起来都很好!

怪异。

4 个答案:

答案 0 :(得分:11)

我正在努力解决同样的问题。我检查了几乎所有的东西,然后怀疑落在会话处理程序上......

我有

session: ~

更改为:

session:
    handler_id:  ~

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

答案 1 :(得分:2)

我和你有同样的问题。

虽然@ 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/

答案 2 :(得分:1)

当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页面。这在两个环境中创建了2-3个sess_xxx文件,在prod中也在dev中创建。这是不好的。这是一个迹象,某种程度上某些东西会向app_dev.php发送一个请求,该请求将加载开发环境,这可能会自动注销您(基于您的应用程序的安全/防火墙配置)。我打开了app_dev.php并添加了一个退出(0)然后突然一切都开始运行良好。所以这就是发生的事情,不知何故这些环境是混合的,对prod的调用最终会触发对dev的调用,这会立即将你注销。

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

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

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

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

答案 3 :(得分:1)

在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));
}