IsUserInRole调用GetRolesForUser吗?

11
当我实现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();
    }

1
很难想象这是可能的,因为它是一个抽象方法。请发布你的实现。 - Hans Passant
2个回答

8

RoleProvider.IsUserInRole(username, password)用于检查给定用户的角色,该用户不是当前登录用户(对于当前登录用户,它也使用Principal.IsInRole)。而对于RolePrincipal,它始终使用GetRolesForUser来缓存角色并在缓存的角色列表中进行角色检查。(source)

可以使用Roles.Provider.IsUserInRole代替Roles.IsUserInRole


6
有一个名为Microsoft角色提供程序解决方案的层,它可以将用户角色缓存到cookie中,因此不需要调用提供程序的GetRolesForUser方法。我认为cookie缓存是Roles类的一部分,只要从RoleProvider基类实现即可兼容。值得一看的是在反射器中查看代码,以了解MS如何实现自己的抽象类以及静态帮助类所做的事情(Roles和Membership)。
尝试在配置文件中的roleManager元素中添加cacheRolesInCookie =“true”,并查看流程是否更改。
由于您正在使用自己的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 方法。

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

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


尝试在角色提供程序上添加cacheRolesInCookie="true",但仍会调用GetRolesForUser。 - Josh
你有找到解决方法吗?如果我传入两个随机字符串,它会进入InUserInRole函数,但如果我在用户名参数中传入我的Active Directory,它会强制使用GetRolesForUser函数!! - Murphybro2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接