在某些应用程序中,即使是登录的用户,也会限制他们可以查看的内容或可以编辑的字段。

为此,MVC 框架提供 AuthorizeAttribute 类。

本主题包含以下各节:

使用 AuthorizeAttribute

如果您使用该特性标记控制器,则限制控制器中的所有操作方法。

这使您可以高度控制谁有权查看网站上的任何页面。

如果站点配置为使用 ASP.NET Forms 身份验证,401 状态代码会导致浏览器将用户重定向到登录页。

派生自 AuthorizeAttribute

Items 属性中,可通过传递到AuthorizeAttribute 的上下文对象访问该属性。


 

[csharp] view plaincopy
  1. [HandleError]  
  2.  public class HomeController : Controller  
  3.  {  
  4.      public ActionResult Index()  
  5.      {  
  6.          ViewData["Message"] = "Welcome to ASP.NET MVC!";  
  7.   
  8.          return View();  
  9.      }  
  10.   
  11.      public ActionResult About()  
  12.      {  
  13.          return View();  
  14.      }  
  15.   
  16.      [Authorize]  
  17.      public ActionResult AuthenticatedUsers()  
  18.      {  
  19.          return View();  
  20.      }  
  21.   
  22.      [Authorize(Roles = "Admin, Super User")]  
  23.      public ActionResult AdministratorsOnly()  
  24.      {  
  25.          return View();  
  26.      }  
  27.   
  28.      [Authorize(Users = "Betty, Johnny")]  
  29.      public ActionResult SpecificUserOnly()  
  30.      {  
  31.          return View();  
  32.      }  
  33.  }  
自定义AuthorizeAttribute

 

网站的权限判断是一个非常普遍的需求,从文章ASP.NET MVC的Action Filter中我们知道实现这样的需求只要从AuthorizeAttribute集成,重写相关的判断逻辑就可以了。这里记录一下:

[csharp] view plaincopy
  1. namespace TokenAcl.Web.Helper   
  2. {   
  3. public class TokenAclAuthorizeAttribute : AuthorizeAttribute   
  4. {   
  5. protected override bool AuthorizeCore(HttpContextBase httpContext)   
  6. {   
  7. bool result = false;   
  8. if (httpContext == null)   
  9. {   
  10. throw new ArgumentNullException("httpContext");   
  11. }   
  12. string[] users = Users.Split(',');   
  13. string[] roles = Roles.Split(',');   
  14. if (!httpContext.User.Identity.IsAuthenticated)   
  15. return false;   
  16. if (roles.Length != 0)   
  17. {   
  18. List<Role> rightRoles = RightClient.GetAllRole(TakenAclMenu.SystemID, TakenAclMenu.UserID);   
  19. foreach (var role in roles)   
  20. {   
  21. if (rightRoles.Where(x => x.Code == role).Count() > 0)   
  22. {   
  23. result = true;   
  24. break;   
  25. }   
  26. }   
  27. }   
  28. if (!result)   
  29. {   
  30. httpContext.Response.StatusCode = 403;   
  31. }   
  32. return result;   
  33. }  
  34. public override void OnAuthorization(AuthorizationContext filterContext)   
  35. {   
  36. base.OnAuthorization(filterContext);   
  37. if (filterContext.HttpContext.Response.StatusCode == 403)   
  38. {   
  39. filterContext.Result = new RedirectResult("/Admin/Dashboard");   
  40. }   
  41. }   
  42. }   
  43. }  

从AuthorizeAttribute继承过来实现了一个类TokenAclAuthorizeAttribute ,重写了方法AuthorizeCore,使用自己开发的权限系统进行权限的验证,如果没有通过认证,这表示没有权限访问,设置HTTP 状态代码为403。 这样还是不行,还得重写另一个方法OnAuthorization。AuthorizeCore方法返回false,MVC 此时将返回的ActionResult是HttpUnauthorizedResult:

 

[csharp] view plaincopy
  1. public class HttpUnauthorizedResult : ActionResult {   
  2. public override void ExecuteResult(ControllerContext context) {   
  3. if (context == null) {   
  4. throw new ArgumentNullException("context");   
  5. }   
  6. // 401 is the HTTP status code for unauthorized access - setting this   
  7. // will cause the active authentication module to execute its default   
  8. // unauthorized handler   
  9. context.HttpContext.Response.StatusCode = 401;   
  10. }   
  11. }  


 

从HttpUnauthorizedResult的源码可以看出,HttpUnauthorizedResult的执行很简单,就是设置当前的HttpContext.Response的状态码为401,这样就回激活authentication module 执行它默认的 unauthorized handler,也就是跳转到登陆页面的,这似乎也不符合逻辑,认证和授权应该是验证的两个方面。这不符合要求,用户已经登陆成功了,只是没有权限而已。我这里只是重写OnAuthorization方法,重定向到一个页面而已,也可以写一个ActionResult。

相关文章:

  • 2021-06-07
  • 2021-11-02
  • 2021-08-02
猜你喜欢
  • 2022-12-23
  • 2021-07-06
  • 2022-12-23
  • 2021-10-16
  • 2022-12-23
  • 2022-12-23
  • 2022-01-15
相关资源
相似解决方案