我有一個MVC控制器基類,我在其上應用了授權屬性,因爲我希望幾乎所有的控制器(以及它們的行爲)都得到授權。覆蓋ASP.NET MVC中的授權屬性
但是我需要一個控制器和另一個控制器的操作未經授權。我想能夠用[Authorize(false)]
或其他東西來裝飾它們,但這不可用。
任何想法?
我有一個MVC控制器基類,我在其上應用了授權屬性,因爲我希望幾乎所有的控制器(以及它們的行爲)都得到授權。覆蓋ASP.NET MVC中的授權屬性
但是我需要一個控制器和另一個控制器的操作未經授權。我想能夠用[Authorize(false)]
或其他東西來裝飾它們,但這不可用。
任何想法?
看來ASP.NET MVC 4通過添加AllowAnonymous屬性「固定」這一點。
David Hayden wrote about this:
[Authorize]
public class AccountController : Controller
{
[AllowAnonymous]
public ActionResult Login()
{
// ...
}
// ...
}
編輯:由於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();
}
}
我個人認爲這將是分裂控制器。只需創建另一個控制器對於您不需要認證的操作。
或者你可以有:
BaseController
不需要身份驗證 - 在這裏你有你的所有 「基地東西」 :)。
BaseAuthController : BaseController
這裏的所有操作都需要驗證。
通過這種方式,您可以在需要時進行身份驗證,只需從特定的類派生即可。
如果你只是想一個動作是一個獲得授權控制器上未經授權,你可以做這樣的事情:
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);
}
}
}
}
我已經想到了這一點,但我希望的一個簡單的解決方案。但是,如果「他們」沒有提供一個,那麼你的解決方案是最好的。 – 2009-04-14 12:07:09