ASP.NET身份的动态访问控制

时间:2016-04-25 17:53:06

标签: c# asp.net asp.net-mvc asp.net-mvc-4 asp.net-identity

也许我已经在"文档"中忽略了这一点。对于ASP.NET身份(2.2.1),但我很难看到创建控制器和界面来管理角色的重点。我理解管理用户的意义(CRUD +分配角色),但就角色的CRUD而言,除非有一种动态检测控制器访问(IsInRole)的方法,否则对我来说没有意义。运行。我有两个问题:

1]当您必须首先在代码中配置应用程序以设置Authorize属性甚至设置角色时,是否有专门的资源和时间为角色创建CRUD?应该有访问权限吗?

2]有没有办法捕获用户从控制器甚至控制器实例请求操作的时刻,以便可能从DB检查该点的权限?

2 个答案:

答案 0 :(得分:1)

我能在SO上找到的最佳答案是:

Dynamically add roles to authorize attribute for controller

这正是我想要完成的,这证明了我为角色创建CRUD的设计是正确的。此时,由于我可以使用上述方法动态地将角色添加到Controller,因此我可以动态创建角色,然后将其包含在Controller的要求中以加强访问。

答案 1 :(得分:0)

  1. 我发现角色非常有用。我没有装饰每个控制器,而是将角色装饰放在我为网站的每个部分定义的抽象类上。然后,一个部分中使用的每个控制器都继承自该部分的抽象类。

  2. 您可以使用Http模块执行此操作并覆盖AuthorizeRequest事件。但我不认为对每个请求进行数据库查询都是个好主意。角色存在于内存中,因此角色授权将更加高效。

  3. 编辑:
    根据您的评论,您可以创建自定义属性来执行此操作。以下是我对如何做到的想法。在OnAuthorization事件中,我将为每个角色创建一个if块。如果用户是该角色的成员,请检查该角色是否可以访问当前控制器。该示例演示了仅一个名为Admin。

    的角色的想法
    using System.Web.Mvc;
    using System.Security.Claims;
    
    namespace MyApp.Filters
    {
        public class CustomAttribute : AuthorizeAttribute
        {
            private List<string> adminControllers;
    
            public CustomAttribute()
            {
                this.adminControllers = new List<string>();
    
                //This would be a DB call
                this.adminControllers.Add("MyApp.Controllers.AccountController");
                this.adminControllers.Add("MyApp.Controllers.AdministrationController");
            }
    
            public override void OnAuthorization(AuthorizationContext filterContext)
            {
                base.OnAuthorization(filterContext);
    
                //Get the roles for the current user
                var identity = (ClaimsIdentity)filterContext.HttpContext.User.Identity;
                var roles = identity.Claims.Where(c => c.Type == ClaimTypes.Role)
                            .Select(c => c.Value).ToList();
    
                //Check if current user has the Admin role
                if (roles.Contains("Admin"))
                {
                    //Check if Admin role has access to current controller
                    if (this.adminControllers.Contains(filterContext.Controller.ToString()))
                    {
                        filterContext.Result = new RedirectResult("~/Home/Error");
                    }
                }
    
    
            }
        }
    }