2009-04-14 179 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); 
      } 
     } 
    } 
}