Symfony2 FOSUserBundle – 针对“用户活动"进行验证登录时的标志 [英] Symfony2 FOSUserBundle – Validate against "user active" flag on login

查看:29
本文介绍了Symfony2 FOSUserBundle – 针对“用户活动"进行验证登录时的标志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的用户有一个标记为活动",如果设置为零或空值,我将不允许登录.

I have a flag on my users for 'active' and if set to zero or null, I will not allow login.

我尝试了几种方法,但都失败了.

I have tried a couple of approaches and come up short.

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

If I do the logout route the flash message is not preserved, so the user sees nothing.

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

I looked into adding a validation on the login form so that it would throw a normal form error if the flag was not set to true, but in that folder (vendor/Bundles/FOS/UserBundle/Form/Type) I find nothing for login form, only registration and such, so I wouldn't know where to put it or where to inherit from in order to override.

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

I also tried as suggested here to manually log out, but that left me with a white screen of death...

对于如何轻松完成此操作有任何建议吗?

Any suggestions how to easily accomplish this?

************** 更新 ************

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

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

I realized that I probably want to go about it adding a validator on the login form. I currently have it coded into the controller of the first route a user gets sent to, but that won't provide much security if a user types a route before logging in, because on a successful login attempt, my default "landing page" after login will not be the route that the user is taken to, but he will be landing on the route of his choice...

***再次更新****

***UPDATE AGAIN ****

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

So the service config file has this...

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

该参数在此处定义...

And that parameter is defined here...

    <parameter key="security.user_checker.class">SymfonyComponentSecurityCoreUserUserChecker</parameter>

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

So in order to modify the login logics I need to override

SymfonyComponentSecurityCoreUserUserChecker

现在我通过在 symfony 应用程序/配置中的我自己的 parameters.ini 中覆盖上面的参数来做到这一点

Now I have done that by overriding that parameter above in my own parameters.ini in the symfony app/config like this

security.user_checker.class  = BizTVUserBundleControllerUserChecker

.. 并将此检查添加到我的 userChecker 覆盖程序中...

.. and added this check to my 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 BizTVUserBundleController;
//namespace SymfonyComponentSecurityCoreUser;

use SymfonyComponentSecurityCoreExceptionCredentialsExpiredException;
use SymfonyComponentSecurityCoreExceptionLockedException;
use SymfonyComponentSecurityCoreExceptionDisabledException;
use SymfonyComponentSecurityCoreExceptionAccountExpiredException;

use SymfonyComponentSecurityCoreUserUserInterface;
use SymfonyComponentSecurityCoreUserUserChecker 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 让我走到这一步!)

* Update nb 3 ******** Now I only have left to make it actually check for the standard user lock which surprisingly it doesn't do out of the box. (Thanks nifr for getting me this far!)

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

My user entity starts off like this, and like Nifr said, I need to implement the AdvancedUserInterface, but this is probably not the way to do it since it still doesn't check for this lock... but it throws me no error message either (if I change them up and put implememts AdvancedUserInterface and then EXTENDs baseUser it throws an error so...)

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

namespace BizTVUserBundleEntity;

use BizTVUserBundleValidatorConstraints as BizTVAssert;
use SymfonyComponentSecurityCoreUserAdvancedUserInterface;

use FOSUserBundleEntityUser as BaseUser;
use DoctrineORMMapping as ORM;

use BizTVBackendBundleEntitycompany as company;

/**
 * @ORMEntity
 * @ORMTable(name="fos_user")
 */
class User extends BaseUser implements AdvancedUserInterface
{

不确定当您扩展基本用户并尝试实现AdvancedUserInterface时您是否会这样做,按照上述方法完成后,我仍然无法使用它应该添加的功能(但它也不会向我抛出任何错误消息),但是如果我像这样交换 EXTENDS 和 IMPLEMENTS 的位置(第 18 行)...

Not sure if that's how you do it when you both extend base user and try and implement AdvancedUserInterface, when done as above I still can't use the features it's supposed to add (but it throws me no error message either), but If I switch places of the EXTENDS and IMPLEMENTS like this (line 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

推荐答案

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

FOSUserBundle / Symfony already has some kind of "active" flag integrated.

FOSUserBundleModelUser提供基本用于此目的的属性锁定"和启用".这两个属性之间的区别如下(引用@stof 的评论 here)

FOSUserBundleModelUser already provides the properties "locked" and "enabled" which are intended basically for this purpose. The difference between those two properties is the following ( quoting @stof's comment here)

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

From the Security component point of view, there is no real difference: both are forbidden to log in. The difference is a semantic one: disabled users are generally users that need to activate their account (for instance, when you activate the need to confirm the email in FOSUserBundle, the user is disabled on creation and enabled on confirmation). On the other hand, locking a user is generally an action done by the admin of the site to ban a user. Using the same field in the database does not make sense as it would allow banned user to have access again by simply going through the confirmation process.

锁定/禁用用户的检查由 AuthenticationListener 实现了 SymfonyComponentSecurityCoreUserUserCheckerInterface.

The check for locked/disabled users is being performed by a UserChecker ( symfony provides this one as @security.user_checker ) in FOSUserBundle's AuthenticationListener which implements SymfonyComponentSecurityCoreUserUserCheckerInterface.

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

Now in order to redirect inactive user's to a different route you would:

  1. 在扩展的 AuthenticationListener 中的 try/catch 块中捕获 SymfonyComponentSecurityCoreExceptionDisabledException
  2. 如果捕获的异常是 InactiveUserException 类型,则将用户重定向到某个路由

可选地将重定向移动到一个新创建的 EventListener/-Subscriber,它在扩展的 AuthenticationListener 中被分派.通过这种方式,您以后可以创建额外的侦听器,即用于日志记录,并将它们订阅到非活动用户登录尝试事件.

Optionally move the redirect to a newly created EventListener/-Subscriber which is being dispatched in the extended AuthenticationListener. This way you could later create additional Listeners i.e. for logging purposes and just subscribe them to the inactive-user login-attempt event.

这篇关于Symfony2 FOSUserBundle – 针对“用户活动"进行验证登录时的标志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆