2009-04-14 88 views
77

我有一个MVC控制器基类,我在其上应用了授权属性,因为我希望几乎所有的控制器(以及它们的行为)都得到授权。覆盖ASP.NET MVC中的授权属性

但是我需要一个控制器和另一个控制器的操作未经授权。我想能够用[Authorize(false)]或其他东西来装饰它们,但这不可用。

任何想法?

回答

70

看来ASP.NET MVC 4通过添加AllowAnonymous属性“固定”这一点。

David Hayden wrote about this

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

    // ... 
} 
96

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

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

你可以创建一个自定义的授权属性从一个可选的布尔参数标准AuthorizeAttribute继承指定授权是否需要与否。

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(); 
    } 
} 
+0

我已经想到了这一点,但我希望的一个简单的解决方案。但是,如果“他们”没有提供一个,那么你的解决方案是最好的。 – 2009-04-14 12:07:09

15

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

或者你可以有:

  • BaseController
    不需要身份验证 - 在这里你有你的所有 “基地​​东西” :)。

  • BaseAuthController : BaseController
    这里的所有操作都需要验证。

通过这种方式,您可以在需要时进行身份验证,只需从特定的类派生即可。

6

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

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); 
      } 
     } 
    } 
}