You can create your own authorization attribute, for example, "AuthorizeAllExceptAdmin". Inside this class, you just need to check if the current user was an administrator, and if they rejected it, otherwise accept it.
Here's a good tutorial , but you will probably get something like:
public class AuthorizeAllExceptAdmin : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { return !httpContext.User.IsInRole(Constants.ROLES_ADMINISTRATOR); } }
Then your controller method will look like this:
[AuthorizeAllExceptAdmin] public ActionResult SomethingOnlyNonAdminsCanDo() { }
Here is an example of a user attribute that accepts roles for failure.
public class DoNotAuthorize : AuthorizeAttribute { private IEnumerable<string> _rolesToReject; public DoNotAuthorize(IEnumerable<string> rolesToReject) { _rolesToReject = rolesToReject; } protected override bool AuthorizeCore(HttpContextBase httpContext) { foreach (var role in _rolesToReject) { if (httpContext.User.IsInRole(role)) return false; } return true; } }
Then your controller method will look like this:
[DoNotAuthorize(new [] {Constants.ROLES_ADMINISTRATOR})] public ActionResult SomethingOnlyNonAdminsCanDo() { }
I would have thought before choosing one of the options above. If you think that you will have several methods (or entire controllers) with similar authorization requirements (i.e., several actions that the administrator cannot perform), I would stick with a non-parameterized user attribute. This way you can develop them all together (only by changing the user attribute) later. For example, perhaps later you want admins to switch to a special mode where they can perform these actions.
Alternatively, if authorization is more diverse among actions, then using a parameterized list makes sense, since they will develop relatively independently.