C# 您可以为控制器启用 [授权] 但为单个操作禁用它吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/329500/
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
Can you enable [Authorize] for controller but disable it for a single action?
提问by Todd Smith
I would like to use [Authorize]
for every action in my admin controller except the Login
action.
我想[Authorize]
用于管理控制器中除Login
操作之外的每个操作。
[Authorize (Roles = "Administrator")]
public class AdminController : Controller
{
// what can I place here to disable authorize?
public ActionResult Login()
{
return View();
}
}
采纳答案by tvanfosson
I don't think you can do this with the standard Authorize attribute, but you could derive your own attribute from AuthorizeAttribute that takes a list of actions to allow and allows access to just those actions. You can look at the source for the AuthorizeAttribute at www.codeplex.comfor ideas on how to do this. If you did, it might look like:
我不认为您可以使用标准 Authorize 属性来执行此操作,但是您可以从 AuthorizeAttribute 派生您自己的属性,该属性接受一系列操作以允许并允许仅访问这些操作。您可以在www.codeplex.com 上查看AuthorizeAttribute 的源代码,以获取有关如何执行此操作的想法。如果你这样做了,它可能看起来像:
[AdminAuthorize (Roles = "Administrator", Exempt = "Login, Logout") ]
public class AdminController : Controller
{
public ActionResult Login()
{
return View();
}
public ActionResult Login()
{
return View();
}
... other, restricted actions ...
}
EDIT: FYI, I eventually ran across a need to do something similar on my own and I went a different direction. I created a default authorization filter provider and apply a global authorize filter. The authorization filter provider uses reflection to check if an action or controller has a specific authorize attribute applied and, if so, defers to it. Otherwise, it applies a default authorization filter. This is coupled with a PublicAttribute derived from AuthorizeAttribute that allows public access. Now, I get default secured access, but can grant public access via [Public]
applied to an action or controller. More specific authorization can also be applied as necessary. See my blog at http://farm-fresh-code.blogspot.com/2011/04/default-authorization-filter-provider.html
编辑:仅供参考,我最终遇到了需要自己做类似的事情,我走向了不同的方向。我创建了一个默认的授权过滤器提供程序并应用了一个全局授权过滤器。授权过滤器提供者使用反射来检查操作或控制器是否应用了特定的授权属性,如果是,则遵循它。否则,它会应用默认的授权过滤器。这与从 AuthorizeAttribute 派生的 PublicAttribute 相结合,允许公共访问。现在,我获得了默认的安全访问权限,但可以通过[Public]
应用于操作或控制器来授予公共访问权限。也可以根据需要应用更具体的授权。请参阅我的博客http://farm-fresh-code.blogspot.com/2011/04/default-authorization-filter-provider.html
回答by MrJavaGuy
You could override the OnAuthorization method of the controller
您可以覆盖控制器的 OnAuthorization 方法
protected override void OnAuthorization(AuthorizationContext filterContext)
{
if ((string)(filterContext.RouteData.Values["action"]) == "Login")
{
filterContext.Cancel = true;
filterContext.Result = Login();
}
}
This works but it is a hack.
这有效,但它是一个黑客。
Full class code used for testing:
用于测试的完整类代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
namespace MvcApplication2.Controllers
{
[HandleError]
[Authorize]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Title"] = "Home Page";
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About()
{
ViewData["Title"] = "About Page";
return View();
}
protected override void OnAuthorization(AuthorizationContext filterContext)
{
if ((string)(filterContext.RouteData.Values["action"]) == "Index")
{
filterContext.Cancel = true;
filterContext.Result = Index();
}
}
}
}
回答by Azat
May be it's not actual, but I wrote my custom attribute:
可能它不是实际的,但我写了我的自定义属性:
public class SelectableAuthorizeAttribute : AuthorizeAttribute
{
public SelectableAuthorizeAttribute(params Type[] typesToExclude)
{
_typesToExlude = typesToExclude;
}
private readonly Type[] _typesToExlude;
public override void OnAuthorization(AuthorizationContext filterContext)
{
bool skipAuthorization = _typesToExlude.Any(type => filterContext.ActionDescriptor.ControllerDescriptor.ControllerType == type);
if (!skipAuthorization)
{
base.OnAuthorization(filterContext);
}
}
}
And then registered it in my global filetrs:
然后在我的全局文件中注册它:
filters.Add(new SelectableAuthorizeAttribute(typeof(MyController)));
Hope that it will be useful for someone
希望它对某人有用
回答by Ben Pretorius
You can decorate your controller with [Authorize] and then you can just decorate the method that you want to exempt with [AllowAnonymous]
你可以用 [Authorize] 装饰你的控制器,然后你可以用 [AllowAnonymous] 装饰你想要豁免的方法