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

Mat*_*der 6 forms flash logout symfony fosuserbundle

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

我已经尝试了几种方法并且做得很短.

如果我执行注销路由,则不会保留Flash消息,因此用户什么也看不到.

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

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

有什么建议如何轻松完成这个?

************** UPDATE ************

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

***再次更新****

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

    <service id="security.user_checker" class="%security.user_checker.class%" public="false" />
Run Code Online (Sandbox Code Playgroud)

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

    <parameter key="security.user_checker.class">Symfony\Component\Security\Core\User\UserChecker</parameter>
Run Code Online (Sandbox Code Playgroud)

所以为了修改我需要覆盖的登录逻辑

Symfony\Component\Security\Core\User\UserChecker
Run Code Online (Sandbox Code Playgroud)

现在我通过覆盖symfony app/config中我自己的parameters.ini上面的参数来完成这个

security.user_checker.class  = BizTV\UserBundle\Controller\UserChecker
Run Code Online (Sandbox Code Playgroud)

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

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

这是整个文件:

<?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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

*更新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
{
Run Code Online (Sandbox Code Playgroud)

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

class User implements AdvancedUserInterface extends BaseUser 
Run Code Online (Sandbox Code Playgroud)

...我收到此错误:

Parse error: syntax error, unexpected T_EXTENDS, expecting '{' in /var/www/cloudsign/src/BizTV/UserBundle/Entity/User.php on line 18
Run Code Online (Sandbox Code Playgroud)

Nic*_*ich 6

FOSUserBundle/Symfony已经集成了某种"主动"标志.

FOS\UserBundle\Model\User已经提供了"锁定"和"启用"属性,这些属性基本上用于此目的.这两个属性之间的区别是以下(报价@ STOF的评论点击这里)

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

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

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

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

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