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

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

问题描述

首先,我没有使用 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.

我的第一次尝试是在 SymfonyComponentSecurityCoreUserUserInterfacegetRoles() 方法中加载和返回所有用户的角色.起初,它看起来像那样奏效.但是在深入了解之后,我注意到这些角色只会在用户登录时刷新.这意味着如果我授予或撤销用户的角色,他将必须注销并重新登录才能使更改生效.但是,如果我撤销用户的安全角色,我希望立即应用该角色,因此我无法接受这种行为.

My first attempt was to load and return all of the user's roles in the getRoles() method from the SymfonyComponentSecurityCoreUserUserInterface. 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/讨论

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

事实证明,有一个接口 SymfonyComponentSecurityCoreUserEquatableInterface 不是为了比较对象身份,而是为了

It turns out that there's an interface SymfonyComponentSecurityCoreUserEquatableInterface 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.

注意:用户对象在会话中被序列化.由于序列化的工作方式,请确保将角色存储在用户对象的字段中,并且不要直接在 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.

只要您点击执行任何类型的授权检查的页面,就会刷新用户角色,并且分析器工具栏会再次显示带有绿点和已验证:是"的用户.

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天全站免登陆