MVC特性认证 AuthorizeAttribute 类

许多 Web 应用程序要求在用户登录之后才授予其对受限制内容的访问权限。 在某些应用程序中,即使是登录的用户,也会限制他们可以查看的内容或可以编辑的字段。

要限制对 ASP.NET MVC 视图的访问,您可以限制对呈现视图的操作方法的访问。 为此,MVC 框架提供 AuthorizeAttribute 类。

有关使用特性的更多信息,请参见利用特性扩展元数据

本主题包含以下各节:

使用 AuthorizeAttribute

当您使用 AuthorizeAttribute 标记一个操作方法时,则限制只有经过身份验证和授权的用户才能访问该操作方法。 如果您使用该特性标记控制器,则限制控制器中的所有操作方法。

Authorize 特性允许您指明将授权限制给预定义角色或各个用户。 这使您可以高度控制谁有权查看网站上的任何页面。

如果未经授权的用户尝试访问用 Authorize 特性标记的方法,则 MVC 框架会返回 401 HTTP 状态代码。 如果站点配置为使用 ASP.NET Forms 身份验证,401 状态代码会导致浏览器将用户重定向到登录页。

派生自 AuthorizeAttribute

如果从 AuthorizeAttribute 类派生,则派生的类型必须为线程安全的类型。 因此,不要在类型本身的实例中存储状态(例如在实例字段中),除非该状态要应用于所有请求。 而是将每个请求的状态存储在 Items 属性中,可通过传递到AuthorizeAttribute 的上下文对象访问该属性。


[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();
     }
 }
自定义AuthorizeAttribute

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

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:

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。


阅读更多
个人分类: MVC 认证
上一篇Ext.TreeNodeCascade让所有Ext的树支持级联选中
下一篇C# int.ToString()
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭