Today in this article we will learn how to do JWT Authentication .NET Core with examples. We shall use .NET Core 3.1 or .NET6 applications with simple easy to understand examples.
We shall cover below aspects of enabling JWT authentication in ASP.NET Core API,
- What is JWT
- Getting started
- Enable the JWT bearer Authentication scheme
- Using Visual Studio
- NuGet Package Manager CLI
- Authorize Method Attribute
- Configure Secretes Key and Token
- JWT secured Token
- .NET – Invoking a Secured method
- JWT Bearer 200 OK (successful)
- JWT Bearer Error 401: Unauthorized
- Generate JWT bearer Token pro-grammatically
- Summary
What is JWT
JSON Web Token( JWT) is an open standard used for securely transmitting information between parties as a JSON object. JSON Web Tokens are very useful for various scenarios like authorization purposes or Information exchange using digitally signed key-value pairs.
Below is a sample JWT token example,
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJleHAiOjE1NzEwMDc3MzQsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0OjQ0MzQxIiwiYXVkIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNDEifQ. Ve2x6ueiHPyrP7wLjpmZrhx7QWrQKnkxWsu_1qUKKLA
Getting started
Create ASP.NET Core 3.1 or .NET 6 project,
Enable the JWT bearer Authentication scheme
Enabling JWT authentication in ASP.NET Core WebAPI is about registering the JWT Authentication middleware within the request pipeline.
Please note that the JWT middleware component was built into .NET Core 2.2 frameworks previously. But ASP.NET Core 3.1 onwards needs to be installed through the Nuget package separately.
Using Visual Studio
OR
NuGet Package Manager CLI
PM>Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -Version <>
Note: Please use the latest available version
Now let’s see the step-by-step required for enabling the JWT bearer scheme. if you are interested in learning how to basic authentication in .NET core, please visit this article.
Please add below using namespaces to use the same in the code,
using Microsoft.IdentityModel.Tokens; using Microsoft.AspNetCore.Authentication.JwtBearer;
In Startup.cs please update ConfigServices() method to register the JWT Authentication scheme.
Please use the AddAuthentication() extension methods for setting up authentication services in a ServiceCollection as below.
Here we have set DefaultAuthenticateScheme as JwtBearerDefaults.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddCors();
services.AddAuthentication(option =>
{
option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = false,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["JwtToken:Issuer"],
ValidAudience = Configuration["JwtToken:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtToken:SecretKey"]))
};
});
}
You may want to set up the configuration accordingly if supporting multiple authentication schemes in the same API.
TokenValidationParameters are explained as below. This is as per the MSDN details mentioned,
- ValidateIssuerSigningKey – Gets or sets a boolean that controls if validation of the SecurityKey that signed the security token is called.
- ValidIssuer – Gets or sets a String that represents a valid issuer that will be used to check against the token’s issuer.
- ValidateIssuer – Gets or sets a value indicating whether the Issuer should be validated. True means, validation is required.
- ValidAudience – Gets or sets a string that represents a valid audience that will be used to check against the token’s audience
- ValidateAudience – Gets or sets a boolean to control if the audience will be validated during token validation.
- ValidateLifetime – Gets or sets a boolean to control if the lifetime will be validated during token validation.
The following is the final implementation of the Configure() method.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors(option => option
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
In the above example, CORS will be needed only if your API needs to support cross-domain calls.
Authorize Method Attribute
The next step is to enable authentication using the [Authorize] attribute as below.
[Authorize] attribute can also be applied at the Controller level (if you need to secure all methods within a Controller)
[HttpGet]
[Authorize]
public async Task<IEnumerable<string>> Get()
{
var accessToken = await HttpContext.GetTokenAsync("access_token");
return new string[] { accessToken };
}
Configure Secretes Key and Token
appsetting.json file has specified the values for the issuer, the audience, and the signing key, and these key-value pairs will be accessible through the Configuration in ASP.NET Core using Dependency Injection easily.
One can supply required values through an Environment variable or YAML or Secrete Storage if any (if the host environment is Cloud etc.)
The configuration file used in applications is shown below.
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"JwtToken": {
"SecretKey": "xxxxxxxxxx...xx",
"Issuer": "your issue address"
}
}
Note–
There is a limitation of the SecretKey length used in the SymmetricSecurityKey before signing and generating the signed credentials.
It’s recommended using a 128-bit key, generated with cryptographic algorithms as per RFC2104.
For .NET/.NET Core, the key Secret key should be a minimum of 128 bits i.e (16 bytes).
JWT secured Token
JWT token will be generated using a simple logic programmatically is already explained in the below article,
Let’s execute the API to validate the authentication and see if it is working fine.
.NET – Invoking a Secured method
Here I am using SOAP UI as a client to verify the token and invoke a secured GET method.
As shown below API response is 200 OK (successful).
We are reading the passed JWT token programmatically with a method.
JWT Bearer 200 OK (successful)
Above we are reading the JWT bearer token from a secured method using the “access_token” key.
The client should always send the Authorization header with the Bearer schema as below.
Authorization: Bearer <token>
Example :
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJleHAiOjE1NzEwMDc3MzQsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0OjQ0MzQxIiwiYXVkIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzNDEifQ.Ve2x6ueiHPyrP7wLjpmZrhx7QWrQKnkxWsu_1qUKKLA
Let’s execute the API with an invalid token. You will start noticing Error 401: Unauthorized
JWT Bearer Error 401: Unauthorized
For any invalid_token, API shall produce JWT Bearer Error 401: Unauthorized
Generate JWT bearer Token pro-grammatically
Please refer to the below few articles,
Do you have any comments or ideas or any better suggestions to share?
Please sound off your comments below.
Happy Coding !!
Summary
Secured programming is not an afterthought process. It needs to be considered on the day first. Today in this article we understood how to use the JWT bearer token to secure ASP .NET Core applications in a few simple easy steps.
Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.
Nice article. you missed authorization part.
Thank you Jishnu. Glad you liked it. Yes. Agree. I shall soon put a separate detailed article on it.
This was a life saver thank you!
Thank you Tom for that feedback and making my a day ! 🙂 Glad it helped you.
Thanks very helpful. I had issue with key size after enabling token size properly.
Hello Almida- Thanks for the your comments. Have a good day!
Thanks , learned JWT today ?
Hello Adeyemi -Thank you. Appreciate it!
Thank you . Nicely explained.
Thanks Ben for your time. Appreciate your feedback.