I'm reading from several resources (books and SO answers) about authorization in WebApi.
Suppose I want to add Custom Attribute which allows access only for Certain Users:
Case #1
I've seen this approach of overriding OnAuthorization
, which sets response if something is wrong
public class AllowOnlyCertainUsers : AuthorizeAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if ( /*check if user OK or not*/)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
}
}
Case #2
But I've also seen this similar example which also overriding OnAuthorization
but with calling to base
:
public override void OnAuthorization(HttpActionContext actionContext)
{
base.OnAuthorization(actionContext);
// If not authorized at all, don't bother
if (actionContext.Response == null)
{
//...
}
}
Then, you check if the
HttpActionContext.Response
is set or not. If it’s not set, it means that the request is authorized and the user is ok
Case #3
But I've also seen this approach of overriding IsAuthorized
:
public class AllowOnlyCertainUsers : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext context)
{
if ( /*check if user OK or not*/)
{
return true;// or false
}
}
}
Case #4
And then I saw similar example one but with calling base.IsAuthorized(context) :
protected override bool IsAuthorized(HttpActionContext context)
{
if (something1 && something2 && base.IsAuthorized(context)) //??
return true;
return false;
}
One more thing
And finally Dominick said here :
You shouldn't override OnAuthorization – because you would be missing [AllowAnonymous] handling.
Questions
-
1) Which methods should I use :
IsAuthorized
orOnAuthorization
? ( or when to use which) -
2) when should I call
base.IsAuthorized or
base.OnAuthorization` ? -
3) Is this how they built it ? that if the response is null then everything is ok ? ( case #2)
NB
Please notice , I'm using ( and want to use ) only AuthorizeAttribute
which already inherits from AuthorizationFilterAttribute
Why ?
Becuase I'm at the first stage in : http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api
Anyway Im asking via extending Authorize attribute .
Best Answer
You will extend
AuthorizationFilterAttribute
if your authorization logic is not dependent on the identity established and roles. For user related authorization, you will extend and useAuthorizeAttribute
. For the former case, you will overrideOnAuthorization
. For the latter case, you will overrideIsAuthorized
. As you could see from the source code of these attributes,OnAuthorization
is marked virtual for you to override if you derive fromAuthorizationFilterAttribute
. On the other hand, theIsAuthorized
method is marked virtual inAuthorizeAttribute
. I believe this is a good pointer to the intended usage.The answer to this question lies in how OO generally works. If you override a method, you can either completely provide a new implementation or piggy back on the implementation provided by parent and enhance the behavior. For example, take the case of
IsAuthorized(HttpActionContext)
. The base class behavior is to check the user/role against what is specified in the filter vs the identity established. Say, you want to do all that but in addition, you want to check something else, may be based on a request header or something. In that case, you can provide an override like this.I'm sorry but don't understand your Q3. BTW, Authorization filter has been around for a long time and people use it for all kinds of things and sometimes incorrectly as well.
The guy who said that is the God of access control - Dominick. Obviously it will be correct. If you look at the implementation of
OnAuthorization
(copied below),the call to
SkipAuthorization
is the part that ensuresAllowAnonymous
filters are applied, that is, authorization is skipped. If you override this method, you loose that behavior. Actually, if you decide to base your authorization on users/roles, at that point you would have decided to derive fromAuthorizeAttribute
. Only correct option left for you at that point will be to overrideIsAuthorized
and not the already overriddenOnAuthorization
, although it is technically possible to do either.PS. In ASP.NET Web API, there is another filter called authentication filter. Idea is that you use that for authentication and authorization filter for authorization, as the name indicates. However, there are lots of examples where this boundary is fudged. Lots of authroization filter examples will do some kind of authentication. Anyways, if you have time and want to understand a bit more, take a look at this MSDN article. Disclaimer: It was written by me.