带有角色的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()); }
例如,在获得授权后,您可能会重定向到客户控制器。 该控制器可能具有您的属性,因此它授权被视为客户的用户,并重定向到客户控制器…哪个具有您的属性,因此它授权用户…
无限循环。