I'm currently trying to implement security in a new ASP MVC 5 application, based on user roles. The goal is to prevent users from accessing certain controllers or controller methods if they don't have a certain role (or higher). Based on what I've read on the question so far, I created an attribute that inherits AuthorizeAttribute which looks like this (MyAppRole is an enum, btw) :
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class AuthorizeRoleOrSuperiorAttribute : AuthorizeAttribute
{
private MyAppRole _authorizedRole;
public AuthorizeRoleOrSuperiorAttribute(MyAppRole authorizedRole)
{ //Breakpoint here
_authorizedRole = authorizedRole;
}
public override void OnAuthorization(HttpActionContext actionContext)
{ //Breakpoint here
base.OnAuthorization(actionContext);
if (!UserInfo.GetUserRoles().Any(r => (int)r >= (int)_authorizedRole))
throw new UnauthorizedAccessException(ErrorsModule.RoleMissing);
}
}
And I call it this way on methods and/or controllers :
[AuthorizeRoleOrSuperior(MyAppRole.Admin)]
public class MyController : Controller
{
[AuthorizeRoleOrSuperior(MyAppRole.Admin)]
public ViewResult Index()
{
[...]
}
[...]
}
I placed a breakpoint on the constructor and the OnAuthorization method but, when I launch the app and call the concerned controller or method, I never hit any of them and the action is called, even though I'm not even logged in.
Note : the AuthorizeAttribute is working properly when I use it.
Any idea what could prevent the attribute to work and filter accesses ?
Are you inheriting the attribute from System.Web.Http.AuthorizeAttribute? It works differently than System.Web.Mvc.AuthorizeAttribute.
Try inheriting from System.Web.Mvc.AuthorizeAttribute instead.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class AuthorizeRoleOrSuperiorAttribute : System.Web.Mvc.AuthorizeAttribute
{
private MyAppRole _authorizedRole;
public AuthorizeRoleOrSuperiorAttribute(MyAppRole authorizedRole)
{ //Breakpoint here
_authorizedRole = authorizedRole;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{ //Breakpoint here
base.OnAuthorization(filterContext);
if (!UserInfo.GetUserRoles().Any(r => (int)r >= (int)_authorizedRole))
throw new UnauthorizedAccessException(ErrorsModule.RoleMissing);
}
}
That should at least make you hit the breakpoint.
Note parameter difference in:
OnAuthorization(AuthorizationContext filterContext)
and
public override void OnAuthorization(HttpActionContext actionContext)
You can also set filterContext.Result = new HttpUnauthorizedResult();
to get the correct 401 http status code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With