也许我在 ASP.NET 身份(2.2.1)的"文档"中的某处忽略了这一点,但我正在努力看到创建用于管理角色的控制器和接口的意义。 我理解管理用户(CRUD +分配角色)的意义,但就角色的 CRUD 而言,除非有一种方法可以在运行时动态检测控制器的访问 (IsInRole),否则角色的 CRUD 对我来说没有意义。 我有两个问题:
1] 当您必须首先在代码中配置应用程序以设置 Authorize
属性以甚至设置应具有访问权限的角色时,将资源和时间用于为角色创建 CRUD 是否有意义?
和
2] 有没有办法捕获用户从控制器甚至控制器实例请求操作的时刻,以便可能从数据库检查该点的权限?
我在SO上能找到的最佳答案是:
动态添加角色以授权控制器的属性
这正是我想要实现的,这证明了我为角色创建 CRUD 的设计是合理的。 此时,由于我可以使用上述方法将角色动态添加到控制器,因此我可以动态创建一个角色,然后将其包含在控制器收紧访问权限的要求中。
-
我发现角色非常有用。我没有修饰每个控制器,而是将角色修饰放在我为网站的每个部分定义的抽象类上。 然后,节中使用的每个控制器都继承自该节的抽象类。
-
您可以使用 Http 模块执行此操作并覆盖 AuthorizeRequest 事件。 但我不认为对每个请求进行数据库查询是一个好主意。 角色存在于内存中,因此角色授权将非常高效。
编辑:
根据您的评论,您可以创建自定义属性来执行此操作。 以下是我对如何做到这一点的想法。 在 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");
}
}
}
}
}