可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I made a new action filter (attribute, similar to [Authorize]) which authorizes access to a controller action based on a session value. However, I'm basically decorating all my controller actions with that attribute (with the exception of very few).
So, I thought it would be better to have that Action Filter always executed except in cases where I attach an [ExemptFromAuthorize] attribute to a controller action? (Maybe via inheriting to my own Controller class?)
How can I do this?
回答1:
Running with jeef3's answer, I came up with this. It could use more error checking and robustness like multiple delimited actions, but the general idea works.
In your specific case, you could test for the session value and decide to return out of the authorization also.
public class AuthorizeWithExemptionsAttribute : AuthorizeAttribute
{
public string Exemption { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.RouteData.GetRequiredString("action") == Exemption)
return;
base.OnAuthorization(filterContext);
}
}
Usage:
[AuthorizeWithExemptions(Roles="admin", ExemptAction="Index")]
public class AdminController : Controller
...
回答2:
Check out my article on codeproject -
http://www.codeproject.com/KB/web-security/AuthorizeWithExemptions.aspx
In this article, I'll provide you with a solution for securing ASP.NET MVC application's controllers in a way that all the actions are secured except those you define as unsecure.
snipper from the code:
public override void OnAuthorization(AuthorizationContext filterContext)
{
ActionDescriptor action = filterContext.ActionDescriptor;
bool IsUnsecured = action.GetCustomAttributes(
typeof(UnsecuredActionAttribute), true).Count() > 0;
//If doesn't have UnsecuredActionAttribute - then do the authorization
filterContext.HttpContext.SkipAuthorization = IsUnsecured;
base.OnAuthorization(filterContext);
}
回答3:
I understand the question is pretty outdated but anyway.. If you wish to apply filter to all actions just add following lines into Global.asax:
protected void Application_Start()
{
// your code here and then
RegisterGlobalFilters(GlobalFilters.Filters);
}
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new MyActionFilterAttribute());
}
And in action filter you can just check if action has any other attributes in following way:
public void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.ActionDescriptor.IsDefined(typeof(AnotherActionAttribute), false))
{
// do what you want to do
}
}
回答4:
Maybe try and add an Except
property to your first attribute?
[MyAuthenticate(Exempt="View")]
public class MyController : Controller
{
public ActionResult Edit()
{
// Protected
}
public ActionResult View()
{
// Accessible by all
}
}
回答5:
You can add the attribute to the class to have it apply to all methods in that class
[Authenticate]
public class AccountController : Controller
{
public ActionResult Index()
{
return View();
}
}
I don't know how to exclude a specific method from a class-level attribute. Maybe use a separate controller for unauthenticated requests?
回答6:
For anyone reading this in 2013+, MVC4 now supports the use of
[AllowAnonymous]
You can put Authorize on the controller, and then Allow Anonymous on
any functions you do not want to authorize.
Example:
[Authorize]
public class HomeController : Controller {
[AllowAnonymous]
public ActionResult Index()
{
}
}
Would this work with a custom [MyAuthorize] filter or does it only work with [Authorize]
回答7:
For anyone reading this in 2013+, MVC4 now supports the use of [AllowAnonymous]
You can put Authorize on the controller, and then Allow Anonymous on any functions you do not want to authorize.
Example:
[Authorize]
public class HomeController : Controller
{
[AllowAnonymous]
public ActionResult Index()
{
}
}