Работает ли Roles.IsUserInRole должным образом в следующем простом сценарии?

В настраиваемом поставщике ролей (унаследованном от RoleProvider) в .NET 2.0 метод IsUserInRole жестко запрограммирован и всегда возвращает true:

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

В приложении ASP.NET, настроенном для использования этого поставщика ролей, следующий код возвращает значение true (как и ожидалось):

Roles.IsUserInRole("any username", "any rolename"); // results in true

Однако следующий код возвращает false:

Roles.IsUserInRole("any rolename"); // results in false

Обратите внимание, что User.IsInRole ("any rolename") также возвращает false.

  1. Это ожидаемое поведение?
  2. Неправильно ли предположить, что перегрузка, которая принимает только имя роли, все равно будет вызывать переопределенную IsUserInRole?

Обновление : обратите внимание, что не существует переопределения, доступного для версии, которая принимает одну строку, что привело к моему предположению в # 2.

12.12.2008 14:28:33
3 ОТВЕТА
РЕШЕНИЕ

Я посмотрел на Roles.IsUserInRole (строка rolename) в отражателе .net, и он разрешается следующим образом:

public static bool IsUserInRole(string roleName)
{
    return IsUserInRole(GetCurrentUserName(), roleName);
}

Я бы посмотрел на вашего текущего пользователя. Вот почему:

private static string GetCurrentUserName()
{
    IPrincipal currentUser = GetCurrentUser();
    if ((currentUser != null) && (currentUser.Identity != null))
    {
        return currentUser.Identity.Name;
    }
    return string.Empty;
}

Я хотел бы поспорить, что это возвращает пустую строку, потому что у вас либо нет текущего пользователя, либо его имя пустая или пустая.

В IsUserInRole(string username, string roleName)методе есть следующий блок кода в самом начале:

   if (username.Length < 1)
   {
       return false;
   }

Если ваш GetCurrentUserName()метод не возвращает ничего значащего, он вернет false до вызова переопределенного метода.

Мораль от этого убрать: Рефлектор отличный инструмент :)

3
12.12.2008 14:59:44
Очень признателен! Я сейчас скачал инструмент Reflector, спасибо, что указал мне на него. Вы были правы, указав пустое имя пользователя. Я использую анонимную аутентификацию, в результате чего идентификатором является System.Security.Principal.GenericIdentity, который имеет пустой атрибут Name.
J c 12.12.2008 16:41:27
Да, я склонен полагаться на отражатель больше, чем на собственную документацию Microsoft :)
Andrew Rollings 12.12.2008 19:19:34

Также будьте осторожны, если вы выбрали cacheRolesInCookie = "true" в конфигурации RoleManager. Если вы добавили новую роль в базу данных, она может искать кэшированную версию в файле cookie.

У меня была эта проблема, и решение состояло в том, чтобы удалить cookie и повторно войти в систему.

0
7.12.2009 14:17:33

Это может кому-то помочь - помните:

Если для аутентификации вы используете элемент управления входом в систему, имя пользователя, введенное в элемент управления, становится HttpContext.Current.User.Identity.Name, который используется в Roles.IsUserInRole (строка rolename) и, более конкретно, - метод GetUser () членства. Поэтому, если это так, убедитесь, что вы переопределили событие Authenticate, подтвердите пользователя в этом методе и установите для имени пользователя значение, которое может использовать ваш пользовательский поставщик членства.

 protected void crtlLoginUserLogin_Authenticate(object sender, AuthenticateEventArgs e)
{
    bool blnAuthenticate = false;
    string strUserName = crtlLoginUserLogin.UserName;

    if (IsValidEmail(strUserName))
    {

        //if more than one user has email address - must authenticate by username.

        MembershipUserCollection users = Membership.FindUsersByEmail(strUserName);
        if (users.Count > 1)
        {
            crtlLoginUserLogin.FailureText = "We are unable to determine which account is registered to that email address. Please enter your Username to login.";

        }
        else
        {
            strUserName = Membership.GetUserNameByEmail(strUserName);
            blnAuthenticate = Membership.ValidateUser(strUserName, crtlLoginUserLogin.Password);

            //setting the userLogin to the correct user name (only on successful authentication)
            if (blnAuthenticate)
            {
                crtlLoginUserLogin.UserName = strUserName;
            }

        }


    }
    else
    {
        blnAuthenticate = Membership.ValidateUser(strUserName, crtlLoginUserLogin.Password);
    }

    e.Authenticated = blnAuthenticate;

}
0
25.03.2010 12:36:01