I've been all over the internet trying to find out why my custom AuthorizeAttribute does not work in my MVC WebApi. I've seen people asking about this kind of thing on SO but nothing has helped me solve my problem yet:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false,
Inherited = false)]
public sealed class CustomAuthorization : AuthorizeAttribute
{
//...
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
// custom auth logic, returns true if authorized, false otherwise
}
}
I am extending from System.Web.Mvc
as opposed to System.Web.Http
. However, my AuthorizeCore(HttpContextBase httpContext)
is never called.
I have a constructor in my CustomAuthorization
class that takes a params string[]
which are the names of my custom permissions required for a particular action, eg:
[CustomAuthorization("Some Permission")]
[System.Web.Http.HttpGet]
public CustomResponse SomeAction()
{
//...
}
What I am hoping to achieve is to have my authorization code fired whenever a request is made to an action decorated with the [CustomAuthorization]
attribute. I also want to be able to return a more descriptive auth failed message if the authorization fails. Not just:
{"Message":"Authorization has been denied for this request."}
I believe this involves overriding HandleUnauthorizedRequest
but how can I do this to provide my own object that a JSON response will serialize?
To summarize, my authorization code is never called by the framework even if I decorate the actions with my [CustomAuthorization]
attribute. It just goes straight to executing the code inside the action.
Secondly, how can I implement the unauthorized responses to serialize a custom JSON object?
Thanks for your help in advance, it is much appreciated!
Ok I eventually solved it and this is how:
public override void OnAuthorization(HttpActionContext actionContext) {
....
if (!authorized) {
actionContext.Response =
actionContext.Request.CreateResponse(
HttpStatusCode.Unauthorized,
new Dictionary<string, string> {
{ "hello", "world" }
}
);
}
}
Which produces the result:
{"hello":"world"}
The Dictionary object is arbitrary, it just demonstrates that a type will be serialized to the Response successfully.
If you don't set the actionContext.Response
then the Request will continue to the target action - ie. it is deemed authorized by this filter.
Hope that helps others in this position.
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