在某些应用程序中,即使是登录的用户,也会限制他们可以查看的内容或可以编辑的字段。
为此,MVC 框架提供 AuthorizeAttribute 类。
。
本主题包含以下各节:
使用 AuthorizeAttribute
如果您使用该特性标记控制器,则限制控制器中的所有操作方法。
这使您可以高度控制谁有权查看网站上的任何页面。
如果站点配置为使用 ASP.NET Forms 身份验证,401 状态代码会导致浏览器将用户重定向到登录页。
派生自 AuthorizeAttribute
Items 属性中,可通过传递到AuthorizeAttribute 的上下文对象访问该属性。
[csharp] view plaincopy
- [HandleError]
- public class HomeController : Controller
- {
- public ActionResult Index()
- {
- ViewData["Message"] = "Welcome to ASP.NET MVC!";
- return View();
- }
- public ActionResult About()
- {
- return View();
- }
- [Authorize]
- public ActionResult AuthenticatedUsers()
- {
- return View();
- }
- [Authorize(Roles = "Admin, Super User")]
- public ActionResult AdministratorsOnly()
- {
- return View();
- }
- [Authorize(Users = "Betty, Johnny")]
- public ActionResult SpecificUserOnly()
- {
- return View();
- }
- }
网站的权限判断是一个非常普遍的需求,从文章ASP.NET MVC的Action Filter中我们知道实现这样的需求只要从AuthorizeAttribute集成,重写相关的判断逻辑就可以了。这里记录一下:
[csharp] view plaincopy
- namespace TokenAcl.Web.Helper
- {
- public class TokenAclAuthorizeAttribute : AuthorizeAttribute
- {
- protected override bool AuthorizeCore(HttpContextBase httpContext)
- {
- bool result = false;
- if (httpContext == null)
- {
- throw new ArgumentNullException("httpContext");
- }
- string[] users = Users.Split(',');
- string[] roles = Roles.Split(',');
- if (!httpContext.User.Identity.IsAuthenticated)
- return false;
- if (roles.Length != 0)
- {
- List<Role> rightRoles = RightClient.GetAllRole(TakenAclMenu.SystemID, TakenAclMenu.UserID);
- foreach (var role in roles)
- {
- if (rightRoles.Where(x => x.Code == role).Count() > 0)
- {
- result = true;
- break;
- }
- }
- }
- if (!result)
- {
- httpContext.Response.StatusCode = 403;
- }
- return result;
- }
- public override void OnAuthorization(AuthorizationContext filterContext)
- {
- base.OnAuthorization(filterContext);
- if (filterContext.HttpContext.Response.StatusCode == 403)
- {
- filterContext.Result = new RedirectResult("/Admin/Dashboard");
- }
- }
- }
- }
从AuthorizeAttribute继承过来实现了一个类TokenAclAuthorizeAttribute ,重写了方法AuthorizeCore,使用自己开发的权限系统进行权限的验证,如果没有通过认证,这表示没有权限访问,设置HTTP 状态代码为403。 这样还是不行,还得重写另一个方法OnAuthorization。AuthorizeCore方法返回false,MVC 此时将返回的ActionResult是HttpUnauthorizedResult:
[csharp] view plaincopy
- public class HttpUnauthorizedResult : ActionResult {
- public override void ExecuteResult(ControllerContext context) {
- if (context == null) {
- throw new ArgumentNullException("context");
- }
- // 401 is the HTTP status code for unauthorized access - setting this
- // will cause the active authentication module to execute its default
- // unauthorized handler
- context.HttpContext.Response.StatusCode = 401;
- }
- }
从HttpUnauthorizedResult的源码可以看出,HttpUnauthorizedResult的执行很简单,就是设置当前的HttpContext.Response的状态码为401,这样就回激活authentication module 执行它默认的 unauthorized handler,也就是跳转到登陆页面的,这似乎也不符合逻辑,认证和授权应该是验证的两个方面。这不符合要求,用户已经登陆成功了,只是没有权限而已。我这里只是重写OnAuthorization方法,重定向到一个页面而已,也可以写一个ActionResult。