Symfony2 FOSUserBundle - 在登录时验证“用户活动”标志

时间:2013-08-29 22:55:11

标签: forms flash symfony logout fosuserbundle

我的用户标记为'active',如果设置为零或null,我将不允许登录。

我已经尝试了几种方法并且做空。

如果我执行注销路由,则不会保留Flash消息,因此用户看不到任何内容。

我考虑在登录表单上添加验证,以便在标志未设置为true时抛出正常的表单错误,但在该文件夹中(vendor / Bundles / FOS / UserBundle / Form / Type)我发现没有登录表单,只有注册等,所以我不知道在哪里放置它或从哪里继承以便覆盖。

我也按照这里的建议尝试手动退出,但是这给我留下了死亡的白屏......

如何轻松完成此任何建议?

** * ** * ** * 的** * ** 更新 ** * ** * ** * ***

我意识到我可能想在登录表单上添加验证器。我目前已将其编码到用户被发送到的第一条路线的控制器中,但如果用户在登录前键入路线,则不会提供太多安全性,因为在成功登录尝试后,我的默认“登陆页面”之后登录将不是用户被带到的路线,但他将登陆他选择的路线......

*** 再次更新 ** * *

所以服务配置文件有这个......

    <service id="security.user_checker" class="%security.user_checker.class%" public="false" />

这个参数在这里定义......

    <parameter key="security.user_checker.class">Symfony\Component\Security\Core\User\UserChecker</parameter>

因此,为了修改登录逻辑,我需要覆盖

Symfony\Component\Security\Core\User\UserChecker

现在我已经通过覆盖symfony app / config中我自己的parameters.ini上面的参数来完成这个了,就像这样

security.user_checker.class  = BizTV\UserBundle\Controller\UserChecker

..并将此检查添加到我的userChecker overrider ...

    //Test for companylock...
    if ( !$user->getCompany()->getActive() ) {
        throw new LockedException('The company of this user is locked.', $user);
    }

这是整个文件:

<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

//Override by Mattias

namespace BizTV\UserBundle\Controller;
//namespace Symfony\Component\Security\Core\User;

use Symfony\Component\Security\Core\Exception\CredentialsExpiredException;
use Symfony\Component\Security\Core\Exception\LockedException;
use Symfony\Component\Security\Core\Exception\DisabledException;
use Symfony\Component\Security\Core\Exception\AccountExpiredException;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserChecker as OriginalUserChecker;

/**
 * UserChecker checks the user account flags.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class UserChecker extends OriginalUserChecker
{
    /**
     * {@inheritdoc}
     */
    public function checkPreAuth(UserInterface $user)
    {

    //Test for companylock...
    if ( !$user->getCompany()->getActive() ) {
        throw new LockedException('The company of this user is locked.', $user);
    }

        if (!$user instanceof AdvancedUserInterface) {
            return;
        }

        if (!$user->isCredentialsNonExpired()) {
            throw new CredentialsExpiredException('User credentials have expired.', $user);
        }


    }

    /**
     * {@inheritdoc}
     */
    public function checkPostAuth(UserInterface $user)
    {

    //Test for companylock...
    if ( !$user->getCompany()->getActive() ) {
        throw new LockedException('The company of this user is locked.', $user);
    }  

        if (!$user instanceof AdvancedUserInterface) {
            return;
        }



        if (!$user->isAccountNonLocked()) {
            throw new LockedException('User account is locked.', $user);
        }

        if (!$user->isEnabled()) {
            throw new DisabledException('User account is disabled.', $user);
        }

        if (!$user->isAccountNonExpired()) {
            throw new AccountExpiredException('User account has expired.', $user);
        }
    }
}

* 更新nb 3 * ** * * *** 现在我只剩下让它实际检查标准用户锁,令人惊讶的是它没有开箱即用。 (感谢nifr让我这么远!)

我的用户实体就像这样开始,就像Nifr说的那样,我需要实现AdvancedUserInterface,但这可能不是这样做的,因为它仍然没有检查这个锁......但是它让我失望也没有错误消息(如果我更改它们并将实现AdvancedUserInterface,然后EXTENDs baseUser它会抛出错误,所以......)

<?php
// src/BizTV/UserBundle/Entity/User.php

namespace BizTV\UserBundle\Entity;

use BizTV\UserBundle\Validator\Constraints as BizTVAssert;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;

use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

use BizTV\BackendBundle\Entity\company as company;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser implements AdvancedUserInterface
{

当你们都扩展基础用户并尝试实现AdvancedUserInterface时,不确定你是怎么做的,如上所述,我仍然无法使用它应该添加的功能(但它也不会抛出任何错误信息),但如果我像这样切换EXTENDS和IMPLEMENTS的位置(第18行)......

class User implements AdvancedUserInterface extends BaseUser 

...我收到此错误:

Parse error: syntax error, unexpected T_EXTENDS, expecting '{' in /var/www/cloudsign/src/BizTV/UserBundle/Entity/User.php on line 18

1 个答案:

答案 0 :(得分:6)

FOSUserBundle / Symfony已经集成了某种“活动”标志。

FOS\UserBundle\Model\User已经提供了“已锁定”和“已启用”属性,这些属性基本上用于此目的。这两个属性之间的区别如下(引用@ stof的评论here

  

从安全组件的角度来看,没有真实的   区别:两者都被禁止登录。区别在于   语义一:禁用用户通常是需要的用户   激活他们的帐户(例如,当你激活他们的需要时)   确认FOSUserBundle中的电子邮件,用户在创建时被禁用   并在确认时启用)。另一方面,锁定用户是   通常是网站管理员为禁止用户而执行的操作。   在数据库中使用相同的字段并没有意义   允许禁止的用户通过简单地访问再次访问   确认过程。

在{FOSUserBundle的UserChecker AuthenticationListener中,Symfony\Component\Security\Core\User\UserCheckerInterface(symfony将此作为@ security.user_checker提供)执行对锁定/禁用用户的检查。

现在,为了将非活动用户重定向到不同的路线,您可以:

  1. 在扩展的AuthenticationListener
  2. 中捕获try / catch块中的Symfony\Component\Security\Core\Exception\DisabledException
  3. 如果捕获的异常类型为InactiveUserException
  4. ,则将用户重定向到某个路由

    (可选)将重定向移动到新创建的EventListener / -Subscriber,它将在扩展的AuthenticationListener中调度。这样您以后可以创建其他侦听器,即用于记录目的,只需将它们订阅到非活动用户登录尝试事件。