开发者

ASP.NET MVC: Can I say [Authorize Roles="Administrators"] on the Controller class, but have one public action?

I started off using the default 开发者_StackOverflow中文版project's AccountController, but I've extended/changed it beyond recognition. However, in common with the original I have a LogOn and LogOff action.

Clearly, the LogOn action must be accessible to everyone. However, since I've added lots of other actions to this controller (to create & edit users), I want 99% of the actions to require administrator role membership.

I could decorate all my actions with [Authorize Roles="Administrators"] but there's a risk I'll forget one. I'd rather make it secure by default, by decorating the controller class itself with that attribute, and then relax the requirement on my LogOn method. Can I do that?

(As in, can I do that out-of-the-box without creating custom classes, etc. I don't want to complicate things more than necessary.)


To override an controller Attribute at the Action level you have to create a custom Attribute and then set the Order property of your custom attribute to a higher value than the controller AuthorizeAttribute. I believe both attributes are then still executed unless your custom attribute generates a result with immediate effect such as redirecting.

See Overriding controller AuthorizeAttribute for just one action for more information.

So I believe in your case you will just have to add the AuthorizeAttribute on the Actions and not at the controller level. You could however create a unit test to ensure that all Actions (apart from LogOn) have an AuthorizeAttribute


You can use AuthorizeAttribute on your class

http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx

For relaxing you can implement for example a custom action filter attribute like this (I didn' test if it works).

public class GetRidOfAutorizationAttribute : AuthorizeAttribute 
{
public override void OnAuthorization(AuthorizationContext filterContext)
{

// you can for example do nothing
filterContext.Result = new EmptyResult(); 

}
}


After way too much time, I came up with a solution.

public class OverridableAuthorize : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var action = filterContext.ActionDescriptor;
        if(action.IsDefined(typeof(IgnoreAuthorization), true)) return;

        var controller = action.ControllerDescriptor;
        if(controller.IsDefined(typeof(IgnoreAuthorization), true)) return;

        base.OnAuthorization(filterContext);
    }
}

Which can be paired with IgnoreAuthorization on an Action

public class IgnoreAuthorization : Attribute
{
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜