Atributo de autorização customizado no MVC 4 com funções

Eu criei um atributo de autorização de base de function personalizado.Minha idéia é que quando um usuário com nome de function “funcionário” Log In não deve ter permissão para acessar a página “admin” por meio de URL. Mas quando eu implementar o [MyRoleAuthorization] no controlador Employee e Log In, o erro diz “Esta página da Web tem um loop de redirecionamento”. Este é o código para [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" })); } } } } 

Meu controlador de funcionário se parece com isso

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

Você pode por favor me ajudar.

Seu código de redirecionamento sempre redirectá o usuário para a ação de índice do funcionário, mesmo quando a ação para a qual você está redirecionando for autenticada para o funcionário. Você precisará fornecer outro conjunto de regras em sua autorização e alterar seu método OnAuthorize.

Tal como

 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; } } 

}

Isto pode então ser decorado como

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

Agora seu código de login deve ser modificado para enviar o usuário para o controlador correto.

Seu maior problema é quando você vai para o controlador de funcionário como funcionário, você é redirecionado para o controlador de funcionário, onde seu atributo redireciona você para o controlador de empregado e assim por diante. Tente evitar o redirecionamento dentro do atributo, pois ele torna seu código frágil e, quando você voltar daqui a alguns anos, não se lembrará de por que suas rotas não funcionam como você pretende.

Tente isto:

 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()); } 

Parece que, quando autorizado, você redireciona para o controlador do cliente, por exemplo. Esse controlador provavelmente tem o seu atributo e, portanto, ele autoriza o usuário, que é visto como um cliente, e redireciona para o controlador do Cliente … O qual tem seu atributo nele e, portanto, autoriza o usuário …

Loop infinito.