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 日:更新了文章和源代码