2012-02-20 65 views
11

我試圖做一些自定義授權,所以我創建了一個控制器覆蓋OnAuthorization方法。我還將Authorize屬性應用於此控制器。 問題是爲什麼OnAuthorization方法在基本表單身份驗證過程之前調用?爲什麼onAuthorization在驗證之前執行?

我想在認證之後授權用戶。 我錯過了什麼嗎?

下面是代碼:

[Authorize] 
    public class AuthorizationController : Controller 
    { 
     protected override void OnAuthorization(AuthorizationContext filterContext) 
     { 
      base.OnAuthorization(filterContext); 

      if (filterContext == null) 
      { 
       throw new ArgumentNullException("filterContext"); 
      } 

      List<string> allowedControllers = new List<string>() { "SecurityController" }; 
      List<string> allowedActions = new List<string>() { "Index" }; 

      string controllerName = filterContext.Controller.GetType().Name; 
      string actionName = filterContext.ActionDescriptor.ActionName; 

      if (!allowedControllers.Contains(controllerName) 
      || !allowedActions.Contains(actionName)) 
      { 
       filterContext.Result = View("UnauthorizedAccess"); 
      } 
     } 
    } 

,我與測試控制器是一樣的東西:

public class SecurityController : AuthorizationController 
{ 

    public ActionResult Index() 
    { 
     return View(); 
    } 

    public ActionResult AnotherIndex() 
    { 
     return View(); 
    } 
} 

回答

15

的第一件事情AuthorizeAttribute不會被檢查,看是否該用戶進行身份驗證。如果他們不是那麼當重定向到登錄頁面將被髮布。

AuthorizeAttribute基本上包裝了認證檢查與授權件:

protected virtual bool AuthorizeCore(HttpContextBase httpContext) { 
     if (httpContext == null) { 
      throw new ArgumentNullException("httpContext"); 
     } 

     IPrincipal user = httpContext.User; 
     if (!user.Identity.IsAuthenticated) { 
      return false; 
     } 

當您使用AuthorizeAttribute沒有角色/用戶,你在你的例子([授權])做的,它基本上是檢查以確保用戶在這種情況下被認證。

我可能會更改您的代碼來覆蓋AuthorizeAttribute,而不是在您的控制器中執行此代碼。你可以做到以下幾點:

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     filterContext.Result = CreateResult(filterContext); 
    } 

    protected ActionResult CreateResult(AuthorizationContext filterContext) 
    { 
     var controllerContext = new ControllerContext(filterContext.RequestContext, filterContext.Controller); 
     var controller = (string)filterContext.RouteData.Values["controller"]; 
     var action = (string)filterContext.RouteData.Values["action"]; 
     // any custom model here 
     var model = new UnauthorizedModel(); 

     // custom logic to determine proper view here - i'm just hardcoding it 
     var viewName = "~/Views/Shared/Unauthorized.cshtml"; 

     return new ViewResult 
     { 
      ViewName = viewName, 
      ViewData = new ViewDataDictionary<UnauthorizedModel>(model) 
     }; 
    } 
} 
+0

好吧,它不會像我期望的那樣發生。對於上面的例子,當我想訪問AnotherIndex操作時,我期望獲得登錄頁面,但是我得到了UnauthorizedAccess。 – misha 2012-02-20 18:13:07

+0

編輯完成後:我明白了,但是如果我重寫AuthorizeAttribute,則無法訪問其他操作,例如將用戶重定向到告訴他他未被授權而不是登錄的頁面。 – misha 2012-02-20 18:17:02

+0

@misha當然可以。是什麼讓你覺得你不能? – Dismissile 2012-02-20 18:17:45

-2
public override void OnAuthorization(AuthorizationContext filterContext) 
{ 
    base.OnAuthorization(filterContext); 
    bool flag = false; 
    string UserId; 
    string[] AssignedRights = null; 

    //Check if Http Context Contains User Name 
    if (HttpContext.Current.User.Identity.Name != null && HttpContext.Current.User.Identity.Name != string.Empty) 
    { 
     //Get User Id from HttpContext 
     UserId = HttpContext.Current.User.Identity.Name; 
     RoleRepository roleRepository = new RoleRepository(); 
     AssignedRights = roleRepository.GetRolesByUser(Convert.ToInt32(UserId)); 
     flag = IsUserAuthorized(filterContext, flag, AssignedRights); 

     if (flag == false) 
     { 

      filterContext.Result = new HttpUnauthorizedResult(); 
     } 
    } 

} 
0

以下爲自定義授權屬性的樣本。

public class AuthLogAttribute:AuthorizeAttribute 
    { 

     public string View { get; set; } 

     public AuthLogAttribute() 
     { 
      View = "AuthorizeFailed"; 
     } 
     public override void OnAuthorization(AuthorizationContext filterContext) 

     { 
      base.OnAuthorization(filterContext); 
      IsUserAuthorized(filterContext); 
     } 

     private void IsUserAuthorized(AuthorizationContext filterContext) 
     { 
      // If the Result returns null then the user is Authorized 
      if(filterContext.Result ==null) 
       return; 

      //If the user is Un-Authorized then Navigate to Auth Failed View 
      if(filterContext.HttpContext.User.Identity.IsAuthenticated) 

      { 
       var vr = new ViewResult(); 
       vr.ViewName = View; 

       ViewDataDictionary dict = new ViewDataDictionary(); 
       dict.Add("Message", "Sorry you are not Authorized to Perform this Action"); 
       vr.ViewData = dict; 

       var result = vr; 
       filterContext.Result = vr; 
      } 

     } 
    } 

控制器就會像下面,

[AuthLog(Roles ="Manager")]  
     public ActionResult Create() 
     { 
      var product = new Product(); 
      return View(product); 
     } 

最後創造新的共享視圖呼叫 「AuthorizeFailed」。

相關問題