【问题标题】:How to allow users with Admin rights to access controller如何允许具有管理员权限的用户访问控制器
【发布时间】:2014-11-11 13:27:00
【问题描述】:

我有一个使用 Windows 身份验证的应用程序。无需太详细,我的应用程序设置了一系列用户,然后授予管理员权限以创建缺勤。如果他们没有管理员权限,则他们无法更改用户或创建缺勤。

我想根据我的数据库中的管理员标志是否设置为 true 来限制对某些控制器/操作的访问。我工作的用户属于多个组,没有可以包含在授权属性角色字符串中的管理员组。

我按照教程 here 进行操作,但由于我有一个数据库优先实体框架模型,实体类继承自 DbContext 而不是身份上下文。

当我运行该应用程序时,我的代码引发了一条错误消息:“mscorlib.dll 中发生了‘System.InvalidOperationException’类型的异常,但未在用户代码中处理

附加信息:实体类型 IdentityRole 不是当前上下文模型的一部分。”我点击查看详细信息,我看到这个“实体类型 IdentityRole 不是当前上下文模型的一部分。”

这是发生错误的代码片段:

        AbsencesEntities context = new AbsencesEntities();

        AbsenceRepository absenceRepository = new AbsenceRepository(context);
        IdentityResult IdRoleResult;
        IdentityResult IdUserResult;

        // Create a RoleStore object by using the UserSecurity object.
        // The RoleStore is only allowed to contain IdentityRole objects.
        var roleStore = new RoleStore<IdentityRole>(context);

        // Create a RoleManager object that is only allowed to contain IdentityRole objects
        // When creating the RoleManager object, you pass in (as a parameter) a new RoleStore
        var roleMgr = new RoleManager<IdentityRole>(roleStore);

        // Then, you create the "canEdit" role if it doesn't already exist
        if(!roleMgr.RoleExists("canEdit"))
        {
            IdRoleResult = roleMgr.Create(new IdentityRole { Name = "canEdit" });
        }

澄清一下,我没有在配置文件中指定任何其他上下文。

我必须有一种方法可以使用 Windows 身份验证并使用返回的 LAN ID 来检查它是否存在于数据库中。然后使用它来检查数据库中的 Admin 标志是否为真。

【问题讨论】:

    标签: c# asp.net asp.net-mvc entity-framework asp.net-mvc-5


    【解决方案1】:

    您可以从 authorizeattribute 继承并覆盖 authorizecore,然后只需使用该属性装饰您的控制器和/或方法来处理这种情况。例如:

    public class PageAuthorizeAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (/*Rolemanager check*/) {
                return true;
            }
            return false;
        }
    
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
            {
                {"action", "PageDenied"}
                ,
                {"controller", "Authorization"}
            });
        }
    }
    

    您可以使用httpContext.User.Identity.Name 来检查用户名。

    [PageAuthorize]
    public class PageController : Controller
    {}
    

    【讨论】:

    • 这太棒了——我用一个控制器试了一下,效果很好。我单击该链接,它会检查用户是否是管理员并让我进入或将我踢出。我想根据登录用户的“管理员”状态隐藏我的视图中指向控制器的链接。我怀疑这是一个不同的问题?
    • 是的,我会把它作为一个新问题发布,这有点超出了这个问题的范围。
    【解决方案2】:

    将 Authorize 属性设置为整个控制器:

    [Authorize(Roles = "Administrator")]
        public class AdminController : Controller
        {
    

    但要使其正常工作,您需要: 创建自定义主体和身份:

    public class CustomIdentity : IIdentity
    {
        private bool _IsAdmin;
        public bool IsAdmin
        {
            get { return _IsAdmin; }
        }
    
        // other properties
        public CustomIdentity(string Login)
        {
            using(DbContext db = new DbContext())
            {
            User user = db.Users.FirstOrDefault(u => u.Login.Equals(Login, StringComparison.CurrentCultureIgnoreCase));
            _IsAdmin = user.IsAdmin;
            }
        }
    }
    
    public class CustomPrincipal : IPrincipal
    {
        private CustomIdentity _Identity;
        public CustomPrincipal(string Login)
        {
            _Identity = new CustomIdentity(Login);
        }
        public bool IsInRole(string role)
        {
            if (_Identity != null)
            {
                return role == "Administrator"? _Identity.IsAdmin: false;
            }
            else
            {
                return false;
            }
        }
        //other properties and code
    }
    

    在 global.asax 中覆盖 PostAuthRequest:

    protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
    {
        if (User.Identity != null && User.Identity.IsAuthenticated)
        {
            CustomPrincipal opPrincipal = new CustomPrincipal(User.Identity.Name);
            HttpContext.Current.User = opPrincipal;
        }
    }
    

    您应该在用户表和类中添加登录列和相同的属性。

    【讨论】:

      猜你喜欢
      • 2015-04-14
      • 2020-11-13
      • 2018-09-02
      • 1970-01-01
      • 2017-07-07
      • 2021-05-23
      • 2020-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多