2014-01-06 161 views
0

我創建了一個自定義的角色基​​授權屬性。我的想法是,當角色名稱爲「employee」的用戶登錄不應該被允許通過URL訪問「admin」頁面。但是,當我在員工控制器中執行[MyRoleAuthorization]並登錄時,錯誤顯示「此網頁具有重定向循環」。 這是[MyRoleAuthorization]具有角色的MVC 4中的自定義授權屬性

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

你能幫幫我。

回答

1

您的重定向代碼總是會將用戶重定向到員工索引操作,即使您正在重定向到的操作對員工進行身份驗證時也是如此。您需要在授權中提供另一組規則並更改您的OnAuthorize方法。

public class MyRoleAuthorization : AuthorizeAttribute 
{ 
/// <summary> 
/// the allowed types 
/// </summary> 
readonly string[] allowedTypes; 

/// <summary> 
/// Default constructor with the allowed user types 
/// </summary> 
/// <param name="allowedTypes"></param> 
public MyRoleAuthorization(params string[] allowedTypes) 
{ 
    this.allowedTypes = allowedTypes; 
} 

/// <summary> 
/// Gets the allowed types 
/// </summary> 
public string[] AllowedTypes 
{ 
    get { return this.allowedTypes; } 
} 

/// <summary> 
/// Gets the authorize user 
/// </summary> 
/// <param name="filterContext">the context</param> 
/// <returns></returns> 
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"); 
} 

/// <summary> 
/// The authorization override 
/// </summary> 
/// <param name="filterContext"></param> 
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(); 
    } 
} 

現在您的登錄代碼應修改用戶發送到正確的控制器。

0

看來,如果授權,您重定向到客戶控制器,例如。此控制器可能具有您的屬性,因此它授權被視爲客戶的用戶,並將其重定向到客戶控制器......其中包含您的屬性,因此授權用戶...

無限循環。

1

你最大的問題是當你作爲員工進入員工控制器時,你被重定向到員工控制器,在那裏你的屬性將你重定向到員工控制器,等等。儘量避免在屬性中的重定向,因爲它使你的代碼脆&當你回來的時間裏,你會不記得爲什麼,你打算

試試這個你的路由不工作:

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