2012-02-20 185 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”。

相关问题