I have implemented a JWT-based authentication by inheriting DelegatingHandler
and adding the class as configuration.MessageHandlers.Add(new MyDelegatingHandle
Use Authentication Filters, which Web API 2 introduced. They perform just authentication, but say nothing about if user has access to a resource or not. Exactly what you need.
public class JwtAuthenticationFilter : IAuthenticationFilter
{
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
var token = GetTokenFromAuthorizeHeader(context.Request);
if (TokenIsValid(token)) {
var principal = CreatePrincipal(token);
// Use context.Principal instead of Thread.CurrentPrincipal
// and HttpContext.Current.User whenever.
context.Principal = principal;
}
return Task.CompletedTask;
}
// TODO: Implement remaining IAuthencitaionFilter members.
}
Apply this JwtAuthenticationFilter
globally to perform authentication for all requests:
// httpConfig is an instance of HttpConfiguration
httpConfig.Filters.Add(new JwtAuthenticationFilter());
In this way user is authenticated if token is OK. But still all users have access to your API - even the ones with invalid token. Let's move further and protect it.
AuthorizeAttribute is what you need to restrict access to Web API from unauthenticated users. You can apply it globally by using the same approach as above:
httpConfig.Filters.Add(new AuthorizeAttribute());
The one who doesn't have valid token won't pass. Good. The last step is to allow access to some particular resources for users with invalid tokens.
From now on AllowAnonymousAttribute
should work. Basically AuthorizeAttribute
just checks if resource is marked by [AllowAnonymous]
and skips authorization in this case.
Generally Web API is protected from unauthenticated users, but some resources can disable authorization by applying [AllowAnonymous]
. JwtAuthenticationFilter
we implemented above works in any case, so users with valid token will be always authenticated - even if a resource allows anonymous access.