覆盖ASP.NET MVC中的授权属性

我有一个MVC控制器基类,我应用了授权属性,因为我想几乎所有的控制器(和他们的行动一起)被授权。

不过,我需要有一个控制器和另一个控制器的行动未经授权。 我想能够用[Authorize(false)]来装饰它们,但是这是不可用的。

有任何想法吗?

编辑:由于ASP.NET MVC 4最好的方法是简单地使用内置的AllowAnonymous属性。

下面的答案是指早期版本的ASP.NET MVC

您可以使用可选的bool参数来创build从标准AuthorizeAttributeinheritance的自定义授权属性,以指定是否需要授权。

 public class OptionalAuthorizeAttribute : AuthorizeAttribute { private readonly bool _authorize; public OptionalAuthorizeAttribute() { _authorize = true; } public OptionalAuthorizeAttribute(bool authorize) { _authorize = authorize; } protected override bool AuthorizeCore(HttpContextBase httpContext) { if(!_authorize) return true; return base.AuthorizeCore(httpContext); } } 

然后你可以使用该属性来修饰你的基础控制器:

 [OptionalAuthorize] public class ControllerBase : Controller { } 

而对于任何不需要授权的控制器,只需使用带有“假”的覆盖 – 例如

 [OptionalAuthorize(false)] public class TestController : ControllerBase { public ActionResult Index() { return View(); } } 

看来ASP.NET MVC 4通过添加一个AllowAnonymous属性来“修复”这个问题。

大卫·海登写道 :

 [Authorize] public class AccountController : Controller { [AllowAnonymous] public ActionResult Login() { // ... } // ... } 

我个人认为这将是分裂控制器。 只需创build另一个控制器对于您不需要身份validation的操作。

或者你可以有:

  • BaseController
    不需要authentication – 在这里你有所有的“基本东西”:)。

  • BaseAuthController : BaseController
    这里的所有操作都需要authentication

这样,你可以在需要时进行身份validation,只需从特定的类派生。

如果你只想要一个行动是未经授权的控制器未经授权,你可以做这样的事情:

 public class RequiresAuthorizationAttribute : ActionFilterAttribute { private readonly bool _authorize; public RequiresAuthorizationAttribute() { _authorize = true; } public RequiresAuthorizationAttribute(bool authorize) { _authorize = authorize; } public override void OnActionExecuting(ActionExecutingContext filterContext) { var overridingAttributes = filterContext.ActionDescriptor.GetCustomAttributes(typeof (RequiresAuthorizationAttribute), false); if (overridingAttributes.Length > 0 && overridingAttributes[0] as RequiresAuthorizationAttribute != null && !((RequiresAuthorizationAttribute)overridingAttributes[0])._authorize) return; if (_authorize) { //redirect if not authenticated if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { //use the current url for the redirect var redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath; //send them off to the login page //var redirectUrl = string.Format("?RedirectUrl={0}", redirectOnSuccess); var loginUrl = LinkBuilder.BuildUrlFromExpression<HomeController>(filterContext.RequestContext, RouteTable.Routes, x => x.Login(redirectOnSuccess)); filterContext.HttpContext.Response.Redirect(loginUrl, true); } } } }