在 ASP.NET MVC 中覆盖授权属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/746998/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Override Authorize Attribute in ASP.NET MVC
提问by Andrei R?nea
I have an MVC controller base class on which I applied the Authorize attribute since I want almost all of the controllers (and their actions along) to be authorized.
我有一个 MVC 控制器基类,我在其上应用了 Authorize 属性,因为我希望几乎所有控制器(及其操作)都得到授权。
However I need to have a controller and an action of another controller unauthorized. I wanted to be able to decorate them with the [Authorize(false)]or something but this is not available.
但是我需要一个控制器和另一个控制器的未经授权的操作。我希望能够用[Authorize(false)]或 什么东西来装饰它们,但这是不可用的。
Any ideas?
有任何想法吗?
采纳答案by Andrei R?nea
It seems ASP.NET MVC 4 'fixed' this by adding an AllowAnonymousattribute.
似乎 ASP.NET MVC 4 通过添加AllowAnonymous属性“修复”了这个问题。
David Hayden wrote about this:
[Authorize]
public class AccountController : Controller
{
[AllowAnonymous]
public ActionResult Login()
{
// ...
}
// ...
}
回答by Steve Willcock
Edit: Since ASP.NET MVC 4 the best approach is simply to use the built-in AllowAnonymousattribute.
编辑:从 ASP.NET MVC 4 开始,最好的方法就是使用内置的AllowAnonymous属性。
The answer below refers to earlier versions of ASP.NET MVC
下面的答案是指早期版本的 ASP.NET MVC
You could create a custom authorisation attribute inheriting from the standard AuthorizeAttribute with an optional bool parameter to specify whether authorisation is required or not.
您可以使用可选的 bool 参数创建从标准 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);
}
}
Then you can decorate your base controller with that attribute:
然后您可以使用该属性装饰您的基本控制器:
[OptionalAuthorize]
public class ControllerBase : Controller
{
}
and for any controllers you don't want authorisation simply use the override with a 'false' - e.g.
对于您不想要授权的任何控制器,只需使用带有“false”的覆盖 - 例如
[OptionalAuthorize(false)]
public class TestController : ControllerBase
{
public ActionResult Index()
{
return View();
}
}
回答by sirrocco
My personal take on this would be to split the controller. Just create another controller For the actions you don't need authentication.
我个人对此的看法是拆分控制器。只需为不需要身份验证的操作创建另一个控制器。
Or you could have :
或者你可以有:
BaseController
doesn't require authentication - here you have all your "base stuff" :).BaseAuthController : BaseController
all actions here require authentication.
BaseController
不需要身份验证 - 在这里你有你所有的“基本东西”:)。BaseAuthController : BaseController
这里的所有操作都需要身份验证。
That way you can have authentication when you want , just by deriving from a specific class.
这样您就可以在需要时进行身份验证,只需从特定类派生即可。
回答by pondermatic
If you just want one action to be unauthorized on an otherwise authorized controller you can do something like this:
如果您只想在其他授权控制器上未经授权执行一项操作,您可以执行以下操作:
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);
}
}
}
}

