IsUserInRole 调用 GetRolesForUser?

发布于 2024-09-30 19:18:03 字数 869 浏览 3 评论 0原文

当我实现 RoleProvider 类并调用 Roles.IsUserInRole(string username, string roleName) 时,代码执行首先转到方法“GetRolesForUser(string username)”。这是为什么呢?当我只是寻找该用户是否属于一个角色的单一值时,我不想迭代所有角色。这是 .NET 角色提供程序类的限制还是我可以采取一些措施来更多地控制代码的执行?

这是调用代码

if (Roles.IsUserInRole(CurrentUser.UserName, "Teacher")) {

这是 IsUserInRole 的实现

public override bool IsUserInRole(string username, string roleName) { return true; }

但代码 GetRolesForUser 总是首先实现:

public override string[] GetRolesForUser(string username) {
        string[] roles = GetAllRoles();
        List<string> userRoles = new List<string>();
        foreach (string role in roles) {
            if (IsUserInRole(username, role)) {
                userRoles.Add(role);
            }
        }
        return userRoles.ToArray();
    }

When I implement the RoleProvider class and call Roles.IsUserInRole(string username, string roleName), code execution first goes to the method 'GetRolesForUser(string username)'. Why is this? I don't want to iterate all roles when I am just looking for the single value of whether that user belongs in one role. Is this a limitation of .NET's role provider class or is there something I can do to control the execution of code a bit more?

Here's the calling code

if (Roles.IsUserInRole(CurrentUser.UserName, "Teacher")) {

And here's the implementation of IsUserInRole

public override bool IsUserInRole(string username, string roleName) { return true; }

But the code GetRolesForUser always gets implemented first:

public override string[] GetRolesForUser(string username) {
        string[] roles = GetAllRoles();
        List<string> userRoles = new List<string>();
        foreach (string role in roles) {
            if (IsUserInRole(username, role)) {
                userRoles.Add(role);
            }
        }
        return userRoles.ToArray();
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

恋你朝朝暮暮 2024-10-07 19:18:03

RoleProvider.IsUserInRole(用户名,密码)用于检查给定用户的角色,该用户不是当前登录用户(对于当前登录用户,它也使用Principal.IsInRole代替)。而对于RolePrincipal,它总是使用GetRolesForUser来缓存角色,并在缓存的角色列表中进行角色检查。 (来源

用户可以Roles.Provider.IsUserInRole 而不是 Roles.IsUserInRole

The RoleProvider.IsUserInRole(username, password) is used for checking roles for a given user which is not the current loggon user(for current logon user, it also use the Principal.IsInRole instead). And for RolePrincipal, it always use the GetRolesForUser to cache the roles and do the role checking among the cached role list. (source)

can user Roles.Provider.IsUserInRole instead of Roles.IsUserInRole

树深时见影 2024-10-07 19:18:03

Microsoft 的角色提供程序解决方案有一个层,可以在 cookie 中缓存用户的角色,因此不需要调用提供程序的 GetRolesForUser 方法。我相信 cookie 缓存是 Roles 类的一部分,因此只要您从 RoleProvider 基类实现,它就应该兼容。值得一看的是 Reflector 中的代码,以了解 MS 如何实现自己的抽象类,以及静态帮助器类的作用(角色和成员身份)

尝试将 cacheRolesInCookie="true" 添加到配置文件中的 roleManager 元素中,并查看流量是否发生变化。

由于您使用的是自己的 RoleProvider 实现,因此您还可以重写 IsUserInRole 方法并提供自己的实现来检查用户是否属于某个角色。

更新: 此代码块在 Roles.IsUserInRole 方法内部调用:

IPrincipal currentUser = GetCurrentUser();
if (((currentUser != null) && (currentUser is RolePrincipal)) && ((((RolePrincipal) currentUser).ProviderName == Provider.Name) && StringUtil.EqualsIgnoreCase(username, currentUser.Identity.Name)))
{
    flag = currentUser.IsInRole(roleName);
}
else
{
    flag = Provider.IsUserInRole(username, roleName);
}

else 块将调用自定义提供程序的 IsUserInRole 方法。

因此您的用户的角色尚未添加到主体对象中。如果您还没有完成这一步,那么好吧。如果没有,请确保您这样做。它将确保每次调用 Roles.IsUserInRole 或 User.IsInRole 时,这些函数都会使用用户角色的内存缓存(加载后),而不必每次都访问数据库。 (尽管基本角色提供程序和角色管理器类应该为您处理这个问题。)

您可以验证角色提供程序的配置文件设置吗?另外,您使用的 .net 版本是什么?您是手动管理登录过程还是使用 .net 登录控件?您是否实现了自定义 Roles 类?或者您正在使用 System.Web.Security.Roles?

There's a layer Microsoft's role provider solution that enables caching a user's roles in a cookie so it doesn't need to call the provider's GetRolesForUser method. I believe the cookie caching is part of the Roles class, so as long as you implement from the RoleProvider base class, it should be compatible. It's worth a look at the code in reflector to get an idea of how MS implements their own abstract classes, and what the static helper classes do (Roles and Membership)

Try adding cacheRolesInCookie="true" to the roleManager element in your config file, and see if the flow changes.

Since you're using your own implementation of a RoleProvider, you can also override the IsUserInRole method and provide your own implementation of checking if a user is in a role.

UPDATE: This block of code gets called inside the Roles.IsUserInRole method:

IPrincipal currentUser = GetCurrentUser();
if (((currentUser != null) && (currentUser is RolePrincipal)) && ((((RolePrincipal) currentUser).ProviderName == Provider.Name) && StringUtil.EqualsIgnoreCase(username, currentUser.Identity.Name)))
{
    flag = currentUser.IsInRole(roleName);
}
else
{
    flag = Provider.IsUserInRole(username, roleName);
}

The else block is what will call your custom provider's IsUserInRole method.

So the roles for your user have not yet been added to the Principal object. If you just haven't gotten around to that step yet, OK. If not, make sure you do that. It will make sure that every time you call Roles.IsUserInRole, or User.IsInRole that those functions will use an in-memory cache of the roles for the user (once loaded) instead of having to go to the database every time. (Although the base role provider and Roles manager class should take care of this for you.)

Can you verify the config file settings for the role provider? Also, what version of .net are you using? Are you manually managing the login process or are you using the .net login control? Have you implemented a custom Roles class? Or are you using the System.Web.Security.Roles?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文