-1

我在我的一个项目中使用 SimpleRoleProvider 但在使用该方法时

Roles.GetRolesForUser(username),它返回数据库中的所有角色,即使用户没有任何角色。

这是一个已知问题,是否有解决方法?

我想我可以手动访问 usersInRoles,但我需要这样做吗?

更新:

经过更多调查后,我发现当我不使用电子邮件地址作为用户名时它可以工作。

有谁知道使用电子邮件地址作为用户名的方法?

var username = GetUserNameById(id);
var test = Roles.GetRolesForUser(username);
var temp = test.Contains("Worker");
if (temp)
4

1 回答 1

0

不幸的是,您提供的有关您当前设置的信息很少,所以我不得不做出一些有根据的猜测。

您正在谈论 SimpleRoleProvider,因此您很可能在 WebMatrx.WebData 中使用 SimpleRoleProvider。源代码在 Github 上可用,让我们看一下:

    public override string[] GetRolesForUser(string username)
    {
        if (!InitializeCalled)
        {
            return PreviousProvider.GetRolesForUser(username);
        }
        using (var db = ConnectToDatabase())
        {
            int userId = SimpleMembershipProvider.GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, username);
            if (userId == -1)
            {
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebDataResources.Security_NoUserFound, username));
            }

            string query = @"SELECT r.RoleName FROM " + UsersInRoleTableName + " u, " + RoleTableName + " r Where (u.UserId = @0 and u.RoleId = r.RoleId) GROUP BY RoleName";
            return db.Query(query, new object[] { userId }).Select<dynamic, string>(d => (string)d[0]).ToArray();
        }
    }

正如我们所看到的,此方法所做的第一件事是通过 SimpleMembershipProvider.GetUserId() 获取所提供用户名的 UserId,如下所示:

    // Not an override ==> Simple Membership MUST be enabled to use this method
    public int GetUserId(string userName)
    {
        VerifyInitialized();
        using (var db = ConnectToDatabase())
        {
            return GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, userName);
        }
    }

    internal static int GetUserId(IDatabase db, string userTableName, string userNameColumn, string userIdColumn, string userName)
    {
        var result = db.QueryValue(@"SELECT " + userIdColumn + " FROM " + userTableName + " WHERE (UPPER(" + userNameColumn + ") = @0)", userName.ToUpperInvariant());
        if (result != null)
        {
            return (int)result;
        }
        return -1;
    }

在这里变得有趣了;在原作者构造 SQL 查询的那一行中,他正在做一些特别的事情。他比较大写形式的用户名(因为您可以将数据库设置为区分大小写的排序规则,并且您的用户将自己注册为“David”并且现在尝试以“david”身份登录,这仅适用于大小写-不敏感的排序规则)但犯了一个错误。在右侧,他正在使用土耳其测试,username.ToUpperInvariant()因为他知道土耳其测试并了解到他应该以不区分文化的形式比较他的字符串,但在左侧,他完全错过了它并使用了 TSQL 的UPPER()函数,该函数使用您的数据库整理。

根据您选择的用户名,数据库排序规则和 UserTable 中的其他用户名SimpleMembershipProvider.GetUserId()仍会返回 UserId,但它是错误的。

请直接致电检查是否是这种情况SimpleMembershipProvider.GetUserId(),如果我的猜测是正确的,您有两个选择

  1. 将用户名列的排序规则更改为 Latin1_General_CI_AI
  2. IRoleProvider基于与您的数据库排序规则一起使用的版本创建您自己的版本SimpleRoleProvider并覆盖.GetUserId()
于 2013-10-11T12:27:12.343 回答