带有角色的MVC 4中的自定义授权属性

我创建了一个自定义的角色基​​本授权属性。我的想法是当不允许角色名为“employee”的用户登录时通过URL访问“admin”页面。 但是当我在Employee控制器中实现[MyRoleAuthorization]并登录时,错误显示“此网页有一个重定向循环”。 这是[MyRoleAuthorization]代码

 public class MyRoleAuthorization : AuthorizeAttribute { string isAuthorized; private string AuthorizeUser(AuthorizationContext filterContext) { if (filterContext.RequestContext.HttpContext != null) { var context = filterContext.RequestContext.HttpContext; if (Convert.ToString(context.Session["RoleName"]) == "Admin") { isAuthorized = "Admin"; } else if (Convert.ToString(context.Session["RoleName"]) == "Employee") { isAuthorized = "Employee"; } else if (Convert.ToString((context.Session["RoleName"])) == "Customer") { isAuthorized = "Customer"; } else { throw new ArgumentException("filterContext"); } } return isAuthorized; } public override void OnAuthorization(AuthorizationContext filterContext) { if (filterContext == null) throw new ArgumentException("filterContext"); if (AuthorizeUser(filterContext) == "Admin") { filterContext.Result = new RedirectToRouteResult (new RouteValueDictionary(new { controller = "Admin" })); } else if (AuthorizeUser(filterContext) == "Employee") { filterContext.Result = new RedirectToRouteResult (new RouteValueDictionary(new { controller = "Employee" })); } else if (AuthorizeUser(filterContext) == "Customer") { filterContext.Result = new RedirectToRouteResult (new RouteValueDictionary(new { controller = "Customer" })); } } } } 

我的员工控制器看起来像这样

  [MyRoleAuthorization] public ActionResult Index() { var employee = db.Employee.Include(e => e.User); return View(employee.ToList()); } 

你能帮我么。

您的重定向代码始终会将用户重定向到“员工索引操作”,即使您重定向到的操作已为该员工进行身份validation。 您需要在授权中提供另一组规则并更改OnAuthorize方法。

 public class MyRoleAuthorization : AuthorizeAttribute { ///  /// the allowed types ///  readonly string[] allowedTypes; ///  /// Default constructor with the allowed user types ///  ///  public MyRoleAuthorization(params string[] allowedTypes) { this.allowedTypes = allowedTypes; } ///  /// Gets the allowed types ///  public string[] AllowedTypes { get { return this.allowedTypes; } } ///  /// Gets the authorize user ///  /// the context ///  private string AuthorizeUser(AuthorizationContext filterContext) { if (filterContext.RequestContext.HttpContext != null) { var context = filterContext.RequestContext.HttpContext; string roleName = Convert.ToString(context.Session["RoleName"]); switch (roleName) { case "Admin": case "Employee": case "Customer": return roleName; default: throw new ArgumentException("filterContext"); } } throw new ArgumentException("filterContext"); } ///  /// The authorization override ///  ///  public override void OnAuthorization(AuthorizationContext filterContext) { if (filterContext == null) throw new ArgumentException("filterContext"); string authUser = AuthorizeUser(filterContext); if (!this.AllowedTypes.Any(x => x.Equals(authUser, StringComparison.CurrentCultureIgnoreCase))) { filterContext.Result = new HttpUnauthorizedResult(); return; } } 

}

然后可以将其装饰为

 public class EmployeeController : Controller { [MyRoleAuthorization("Employee")] public ActionResult Index() { return View(); } } 

现在应该修改您的登录代码以将用户发送到正确的控制器。

您最大的问题是当您作为员工转到员工控制器时,您将被重定向到员工控制器,您的属性会将您重定向到员工控制器等等。 尽量避免在属性中重定向,因为它会使您的代码变得脆弱,当您在几年后回来时,您将不记得为什么您的路由无法按预期工作

试试这个:

 public class MyRoleAuthorization : AuthorizeAttribute { public string Role{get;set;} private string AuthorizeUser(AuthorizationContext filterContext) { if (filterContext.RequestContext.HttpContext != null) { var context = filterContext.RequestContext.HttpContext; return (string)context.Session["RoleName"]; } throw new ArgumentException("filterContext"); } public override void OnAuthorization(AuthorizationContext filterContext) { if (filterContext == null) throw new ArgumentException("filterContext"); var role = AuthorizeUser(filterContext); if (role.Equals(Role)) { // insert positive outcome from role check, ie let the action continue } else { // denied! redirect to login page or show denied page (403) } } } [MyRoleAuthorization("Employee")] public ActionResult Index() { var employee = db.Employee.Include(e => e.User); return View(employee.ToList()); } 

例如,在获得授权后,您可能会重定向到客户控制器。 该控制器可能具有您的属性,因此它授权被视为客户的用户,并重定向到客户控制器…哪个具有您的属性,因此它授权用户…

无限循环。