ASP.NET MVC - AuthorizeWithExemptionsAttribute






4.57/5 (5投票s)
这个基础控制器将保护您的所有操作,除了那些被标记为“UnsecuredAction”的操作。
引言
在本文中,我将向您提供一种解决方案,以保护 ASP.NET MVC 应用程序的控制器,使其所有操作都受到保护,除了您定义为不安全的操作(默认情况下,除非您将操作定义为安全,否则所有操作都是不安全的)。
我在 ASP.NET MVC 授权模型中遇到一个问题,该模型是基于选择加入的。您可以使用 [Authorize] 属性来保护一个操作或控制器。问题是,如果您想保护整个控制器,并使控制器中的某些操作不受到保护,您就无法做到。
本文将向您解释如何保护整个控制器,并在其中使某些操作不受到保护。
该项目是在 Visual Studio 2010 中作为 ASP.NET MVC 2 项目编写的。
背景
我一直在寻找解决该问题的方法,但没有找到合理的解决方案。其他解决方案建议
- 将不安全的操作移动到另一个控制器(未受保护)
- 编写 AuthorizeCore方法,使其依赖于操作的名称
- 将 [Authorize]属性放在所有操作上,除了不安全的操作
在本文中,我将向您提供我对这个问题的解决方案。
Using the Code
要使用此代码,您需要让您的控制器放置任何继承自 AuthorizeWithExemptionsAttribute 的 [CustomAuthorize] 属性在您的控制器上。调用此控制器的任何操作都将包含授权检查。如果您想将一个操作标记为不安全,只需将 [UnsecuredAction] 属性放在它上面即可。
解释
此解决方案的核心在于 OnAuthorization 方法中的 [AuthorizeWithExemptions] 属性。此方法检查被调用的操作是否具有 UnsecuredActionAttribute,如果有,则将 filterContext.HttpContext.SkipAuthorization 标记为 true。
public override void OnAuthorization(AuthorizationContext filterContext)
{
    ActionDescriptor action = filterContext.ActionDescriptor;
    bool IsUnsecured = action.GetCustomAttributes(
                         typeof(UnsecuredActionAttribute), true).Count() > 0;
    //If doesn't have UnsecuredActionAttribute - then do the authorization
    filterContext.HttpContext.SkipAuthorization = IsUnsecured;
    base.OnAuthorization(filterContext);
}
然后,CustomAuthorizeAttribute 仅在 SkipAuthorization 为 false 时才执行授权检查。
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
  if (httpContext.SkipAuthorization)
  {
      return true;
  }
  // Do any authorization logic here
  return httpContext.Request.QueryString["password"] == "password";
}
* 当然,永远不要在 QueryString 中提供密码,这样做只是为了示例的方便性。
因此,现在,当您尝试调用受保护的控制器时,您将收到 HTTP 错误代码 401:未授权。
 
 
而不安全的控制器无需任何授权即可工作。
 
 
历史
- 2010 年 8 月 23 日:初始发布
- 2010 年 8 月 24 日:更新了文章和源代码


