MVC自定义角色提供者如何将其连接到HttpContext.Current.User.IsInRole(“myrole”)

时间:2011-11-01 22:50:10

标签: asp.net-mvc authentication

我有一个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 个答案:

答案 0 :(得分:11)

如果您已将RoleProvider作为web.config中应用程序的角色提供程序挂钩,那么这应该会自动生效;框架将在请求开始时为经过身份验证的用户创建RolePrincipal,该用户将在您的角色提供程序上调用GetRolesForUser方法,并将IIdentity中的名称作为用户名传递。

RolePrincipal的{​​{1}}方法的框架实现是这样的(我添加了评论)

IsInRole(string role)

在RoleProvider 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; } 方法中设置一个断点,以确保正确调用它,并检查GetRolesForUserIPrincipal)以确保它的类型为{{1对于经过身份验证的用户。

答案 1 :(得分:5)

抱歉,我在这里参加派对迟到了;

为了其他有相同问题的人的利益 - Russ Cam's答案可以找到答案。

就我而言,我的自定义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

上有关此主题的非常好的教程