I'm trying to support JWT bearer token (Json Web Token) in my web api application and I'm getting lost.
I see support for .net core
and for OWIN
applications.
I'm currently hosting my application over the IIS
.
How can I achieve this authentication module in my application? Is there any way I can use the <authentication>
configuration similar to the way I use form's\windows authentication?
I've managed to achieve it with minimal effort (just as simple as with ASP.NET Core).
For that I use OWIN
Startup.cs
file andMicrosoft.Owin.Security.Jwt
library.In order for the app to hit
Startup.cs
we need to amendWeb.config
:Here's how
Startup.cs
should look:Many of you guys use ASP.NET Core nowadays, so as you can see it doesn't differ a lot from what we have there.
It really got me perplexed first, I was trying to implement custom providers, etc. But I didn't expect it to be so simple.
OWIN
just rocks!Just one thing to mention - after I enabled OWIN Startup
NSWag
library stopped working for me (e.g. some of you might want to auto-generate typescript HTTP proxies for Angular app).The solution was also very simple - I replaced
NSWag
withSwashbuckle
and didn't have any further issues.Ok, now sharing
ConfigHelper
code:Another important aspect - I sent JWT Token via Authorization header, so typescript code looks for me as follows:
(the code below is generated by NSWag)
See headers part -
"Authorization": "Bearer " + localStorage.getItem('token')
I also implement Jason Web Token API in my project, you can download from this link JWT API Token. You can use
[authorize]
to check if a user is authenticated or not?I think you should use some 3d party server to support the JWT token and there is no out of the box JWT support in WEB API 2.
However there is an OWIN project for supporting some format of signed token (not JWT). It works as a reduced OAuth protocol to provide just a simple form of authentication for a web site.
You can read more about it e.g. here.
It's rather long, but most parts are details with controllers and ASP.NET Identity that you might not need at all. Most important are
There you can read how to set up endpoint (e.g. "/token") that you can access from frontend (and details on the format of the request).
Other steps provide details on how to connect that endpoint to the database, etc. and you can chose the parts that you require.
I answered this question: How to secure an ASP.NET Web API 4 years ago using HMAC.
Now, lots of things changed in security, esp JWT is getting popular. In here, I will try to explain how to use JWT in the simplest and basic way that I can, so we won't get lost from jungle of OWIN, Oauth2, ASP.NET Identity... :).
If you don't know JWT token, you need to take a look a little bit at:
https://tools.ietf.org/html/rfc7519
Basically, a JWT token look like:
Example:
JWT token has three sections:
If you use the website jwt.io with token above, you can decode and see the token like below:
Technically, JWT uses signature which is signed from headers and claims with security algorithm specified in the headers (example: HMACSHA256). Therefore, JWT is required to be transferred over HTTPs if you store any sensitive information in claims.
Now, in order to use JWT authentication, you don't really need an OWIN middleware if you have legacy Web Api system. The simple concept is how to provide JWT token and how to validate token when the request comes. That's it.
Back to the demo, to keep JWT token lightweight, I only store
username
andexpiration time
in JWT. But this way, you have to re-build new local identity (principal) to add more information like: roles.. if you want to do role authorization. But, if you want to add more information into JWT, it's up to you, very flexible.Instead of using OWIN middleware, you can simply provide JWT token endpoint by using action from controller:
This is naive action, in production you should use POST request or Basic Authentication endpoint to provide JWT token.
How to generate the token based on
username
?You can use the NuGet package called
System.IdentityModel.Tokens.Jwt
from MS to generate the token, or even another package if you like. In the demo, I useHMACSHA256
withSymmetricKey
:The endpoint to provide the JWT token is done, now, how to validate the JWT when the request comes, in the demo I have built
JwtAuthenticationAttribute
which inherits fromIAuthenticationFilter
, more detail about authentication filter in here.With this attribute, you can authenticate any action, you just put this attribute on that action.
You also can use OWIN middleware or DelegateHander if you want to validate all incoming request for your WebApi (not specific on Controller or action)
Below is the core method from authentication filter:
The workflow is, using JWT library (NuGet package above) to validate JWT token and then return back
ClaimsPrincipal
. You can perform more validation like check whether user exists on your system and add other custom validations if you want. The code to validate JWT token and get principal back:If the JWT token is validated and principal is return, you should build new local identity and put more information into it to check role authorization.
Remember to add
config.Filters.Add(new AuthorizeAttribute());
(default authorization) at global scope in order to prevent any anonymous request to your resources.You can use Postman to test the demo:
Request token (naive as I mentioned above, just for demo):
Put JWT token in the header for authorized request, example:
The demo is put in here: https://github.com/cuongle/WebApi.Jwt