Пользовательский ролевой поставщик MVC, как подключить его к HttpContext.Current.User.IsInRole ("myrole") - PullRequest
8 голосов
/ 02 ноября 2011

У меня есть приложение MVC, и я написал для него специальный ролевой поставщик, как показано ниже:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using VectorCheck.Models;

namespace VectorCheck.Security
{
    public class MyRoleProvider : RoleProvider
    {
        private VectorCheckRepository<User> _repository { get; set; }

        public MyRoleProvider()
        {
            _repository = new VectorCheckRepository<User>();
        }

        public MyRoleProvider(VectorCheckRepository<User> repository)
        {
            _repository = repository;
        }

        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override string ApplicationName
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public override void CreateRole(string roleName)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            throw new NotImplementedException();
        }

        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            throw new NotImplementedException();
        }

        public override string[] GetAllRoles()
        {
            throw new NotImplementedException();
        }

        public override string[] GetRolesForUser(string username)
        {
            var user = _repository.GetUser(username);

            return new string[] { user.Role.Name };
        }

        public override string[] GetUsersInRole(string roleName)
        {
            throw new NotImplementedException();
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            var user = _repository.GetUser(username);

            return string.Compare(user.Role.Name, roleName, true) == 0;
        }

        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override bool RoleExists(string roleName)
        {
            throw new NotImplementedException();
        }
    }
}

Это действительно хорошо работает с ограничением доступа к контроллерам и действиям с помощью:

[Authorize(Roles = "Administrator")]

над контроллером или действием.

Я также хочу ограниченный доступ к некоторым вещам в представлении, используя:

HttpContext.Current.User.IsInRole("Administrator")

Этот метод не является частью моего ролевого провайдера, хотя и не переопределяется.

Кто-нибудь знает, как это сделать и для этого метода?

Ответы [ 2 ]

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

Если вы подключили свой RoleProvider в качестве поставщика ролей для приложения в web.config, то это должно работать автоматически;платформа создаст RolePrincipal для аутентифицированного пользователя в начале запроса, который вызовет метод GetRolesForUser вашего поставщика ролей, передавая имя из IIdentity в качестве имени пользователя.

Фреймворковая реализация метода RolePrincipal IsInRole(string role) выглядит примерно так (я добавил комментарии)

public bool IsInRole(string role) 
{ 
    if (_Identity == null)
        throw new ProviderException(SR.GetString(SR.Role_Principal_not_fully_constructed)); 

    if (!_Identity.IsAuthenticated || role == null)
        return false;
    role = role.Trim(); 
    if (!IsRoleListCached) {
        _Roles.Clear(); 

        // here the RoleProvider is used to get the roles for the user
        // and are cached in a collection on the RolePrincipal so that
        // they are only fetched once per request
        string[] roles = Roles.Providers[_ProviderName].GetRolesForUser(Identity.Name); 
        foreach(string roleTemp in roles)
            if (_Roles[roleTemp] == null) 
                _Roles.Add(roleTemp, String.Empty);

        _IsRoleListCached = true;
        _CachedListChanged = true; 
    }
    return _Roles[role] != null; 
} 

Установите точку останова внутри вашего метода RoleProvider GetRolesForUser, чтобы убедиться, что он используетсявызван правильно, а также проверьте IPrincipal (HttpContext.Current.User), чтобы убедиться, что он относится к типу RolePrincipal для аутентифицированного пользователя.

5 голосов
/ 27 июня 2012

Извините, что я опоздал на вечеринку здесь;

Для блага других людей с такой же проблемой - Ответ Russ 100 - это место для поиска ответа.

В моем случае у моего пользовательского roleManager не было 'enabled = "true" и cacheRolesInCookie = "true".Похоже, это остановило вызов GetRolesForUser.

Рабочий код для web.config:

<roleManager defaultProvider="CustomUserRolesMVCRoleProvider" enabled="true" cacheRolesInCookie="true">

Действительно хорошее руководство по этой теме на http://www.brianlegg.com/post/2011/05/09/Implementing-your-own-RoleProvider-and-MembershipProvider-in-MVC-3.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...