IsUserInRole вызывает GetRolesForUser? - PullRequest
       10

IsUserInRole вызывает GetRolesForUser?

11 голосов
/ 02 ноября 2010

Когда я реализую класс RoleProvider и вызываю Roles.IsUserInRole (строка 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();
    }

Ответы [ 2 ]

8 голосов
/ 07 декабря 2011

RoleProvider.IsUserInRole (имя пользователя, пароль) используется для проверки ролей для данного пользователя, который не является текущим пользователем входа в систему (для текущего пользователя входа в систему вместо этого он также использует Principal.IsInRole).А для RolePrincipal всегда используется GetRolesForUser для кэширования ролей и проверки ролей в списке кэшированных ролей.( источник )

может пользователь Roles.Provider.IsUserInRole вместо Roles.IsUserInRole

6 голосов
/ 03 ноября 2010

Существует многоуровневое решение поставщика ролей Microsoft, которое позволяет кэшировать роли пользователя в файле cookie, поэтому нет необходимости вызывать метод GetRolesForUser провайдера.Я считаю, что кэширование файлов cookie является частью класса Roles, поэтому, пока вы реализуете из базового класса RoleProvider, оно должно быть совместимым.Стоит взглянуть на код в рефлекторе, чтобы понять, как 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 вашего пользовательского провайдера.method.

Таким образом, роли вашего пользователя еще не добавлены в объект Principal.Если вы просто еще не дошли до этого шага, хорошо.Если нет, убедитесь, что вы делаете это.Он будет гарантировать, что каждый раз, когда вы вызываете Roles.IsUserInRole или User.IsInRole, эти функции будут использовать кэш в памяти ролей для пользователя (после загрузки) вместо того, чтобы каждый раз обращаться к базе данных.(Хотя поставщик основной роли и класс менеджера ролей должны позаботиться об этом за вас.)

Можете ли вы проверить параметры файла конфигурации для поставщика роли?Кроме того, какую версию .net вы используете?Вы вручную управляете процессом входа в систему или используете контроль входа в систему .net?Вы реализовали собственный класс ролей?Или вы используете System.Web.Security.Roles?

...