什么时候刷新用户角色以及如何强制执行? [英] When are user roles refreshed and how to force it?

查看:117
本文介绍了什么时候刷新用户角色以及如何强制执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我没有使用FOSUserBundle,也不能,因为我正在移植具有其自己的模型层(此处没有Doctrine/Mongo/任何东西)和其他非常自定义行为的旧版系统.

First off, I'm not using FOSUserBundle and I can't because I'm porting a legacy system which has its own Model layer (no Doctrine/Mongo/whatsoever here) and other very custom behavior.

我正在尝试将旧式角色系统与Symfony的系统连接起来,以便可以在控制器和视图中使用本机symfony安全性.

I'm trying to connect my legacy role system with Symfony's so I can use native symfony security in controllers and views.

我的第一个尝试是从Symfony\Component\Security\Core\User\UserInterface加载并返回getRoles()方法中所有用户角色.起初,它看起来像是可行的.但是,在更深入地了解之后,我注意到这些角色仅在用户登录时才刷新.这意味着,如果我从用户授予或撤消角色,则他将不得不注销并重新登录以使更改生效.但是,如果我撤消了用户的安全角色,则希望立即应用该角色,以使我无法接受这种行为.

My first attempt was to load and return all of the user's roles in the getRoles() method from the Symfony\Component\Security\Core\User\UserInterface. At first, it looked like that worked. But after taking a deeper look, I noticed that these roles are only refreshed when the user logs in. This means that if I grant or revoke roles from a user, he will have to log out and back in for the changes to take effect. However, if I revoke security roles from a user, I want that to be applied immediately, so that behavior isn't acceptable to me.

我希望Symfony要做的是在每个请求上重新加载用户的角色,以确保他们是最新的.我已经实现了一个自定义用户提供程序,并且在每个请求上都调用了它的refreshUser(UserInterface $user)方法,但是角色并没有得到刷新.

What I want Symfony to do is to reload a user's roles on every request to make sure they're up-to-date. I have implemented a custom user provider and its refreshUser(UserInterface $user) method is being called on every request but the roles somehow aren't being refreshed.

要在我的UserProvider中加载/刷新用户的代码如下所示:

The code to load / refresh the user in my UserProvider looks something like this:

public function loadUserByUsername($username) {
    $user = UserModel::loadByUsername($username); // Loads a fresh user object including roles!
    if (!$user) {
        throw new UsernameNotFoundException("User not found");
    }
    return $user;
}

(refreshUser看起来很相似)

有没有一种方法可以使Symfony在每个请求上刷新用户角色?

Is there a way to make Symfony refresh user roles on each request?

推荐答案

因此,经过几天的尝试,找到了可行的解决方案并将其添加到Symfony2用户邮件列表中,我终于找到了它.以下内容摘自 https://groups.google.com/上的讨论. d/topic/symfony2/NDBb4JN3mNc/discussion

So after a couple of days trying to find a viable solution and contributing to the Symfony2 user mailing list, I finally found it. The following has been derived from the discussion at https://groups.google.com/d/topic/symfony2/NDBb4JN3mNc/discussion

事实证明,有一个接口Symfony\Component\Security\Core\User\EquatableInterface并非用于比较对象身份,而恰好是

It turns out that there's an interface Symfony\Component\Security\Core\User\EquatableInterface that is not intended for comparing object identity but precisely to

测试两个对象在安全性和重新身份验证上下文中是否相等

test if two objects are equal in security and re-authentication context

在您的用户类(已经实现UserInterface的类)中实现该接口.实现唯一需要的方法isEqualTo(UserInterface $user),以便在当前用户的角色与传递的用户的角色不同时返回false.

Implement that interface in your user class (the one already implementing UserInterface). Implement the only required method isEqualTo(UserInterface $user) so that it returns false if the current user's roles differ from those of the passed user.

注意:User对象在会话中被序列化.由于序列化的工作方式,请确保将角色存储在用户对象的字段中,并且不要直接在getRoles()方法中检索它们,否则所有这些都将无效!

Note: The User object is serialized in the session. Because of the way serialization works, make sure to store the roles in a field of your user object, and do not retrieve them directly in the getRoles() Method, otherwise all of that won't work!

以下是特定方法的外观示例:

Here's an example of how the specific methods might look like:

protected $roles = null;

public function getRoles() {

    if ($this->roles == null) {
        $this->roles = ...; // Retrieve the fresh list of roles
                            // from wherever they are stored here
    }

    return $this->roles;
}

public function isEqualTo(UserInterface $user) {

    if ($user instanceof YourUserClass) {
        // Check that the roles are the same, in any order
        $isEqual = count($this->getRoles()) == count($user->getRoles());
        if ($isEqual) {
            foreach($this->getRoles() as $role) {
                $isEqual = $isEqual && in_array($role, $user->getRoles());
            }
        }
        return $isEqual;
    }

    return false;
}

此外,请注意,当角色实际更改并重新加载页面时,探查器工具栏可能会告诉您您的用户未通过身份验证.另外,查看探查器,您可能会发现角色实际上并没有得到刷新.

Also, note that when the roles actually change and you reload the page, the profiler toolbar might tell you that your user is not authenticated. Plus, looking into the profiler, you might find that the roles didn't actually get refreshed.

我发现刷新角色实际上是有效的.只是,如果没有命中任何授权约束(没有@Secure批注,防火墙中没有必需的角色等),则刷新实际上并没有完成,并且用户处于未认证"状态.

I found out that the role refreshing actually does work. It's just that if no authorization constraints are hit (no @Secure annotations, no required roles in the firewall etc.), the refreshing is not actually done and the user is kept in the "unauthenticated" state.

只要您点击执行任何类型的授权检查的页面,就会刷新用户角色,并且探查器工具栏会向用户显示一个绿点并再次显示"Authenticated:yes".

As soon as you hit a page that performs any kind of authorization check, the user roles are being refreshed and the profiler toolbar displays the user with a green dot and "Authenticated: yes" again.

对我来说,这是可以接受的行为-希望对您有所帮助:)

That's an acceptable behavior for me - hope it was helpful :)

这篇关于什么时候刷新用户角色以及如何强制执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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