Understanding API Authentication Using JWT Bearer Tokens
In the modern landscape of web development, securing APIs is paramount. One of the most robust methods to achieve this is through API authentication using JWT (JSON Web Tokens) as Bearer tokens. This blog post will delve into the what, why, and how of JWT Bearer Token authentication.
What is JWT?
JWT, or JSON Web Token, is an open standard (RFC 7519) for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
Structure of a JWT
A JWT comprises three parts separated by dots (.): Header, Payload, and Signature.
- Header: The header typically consists of two parts: the type of token (JWT) and the signing algorithm (e.g., HMAC SHA256 or RSA).
{
"alg": "HS256",
"typ": "JWT"
}
- Payload: The payload contains the claims. Claims are statements about an entity (typically, the user) and additional data. There are three types of claims: registered, public, and private claims.
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
- Signature: To create the signature part, you have to take the encoded header, the encoded payload, a secret, and the algorithm specified in the header, and sign that.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
Why Use JWT for API Authentication?
- Statelessness: JWTs are stateless; the server doesn't need to store session information. This makes them scalable and reduces the load on the server.
- Security: JWTs are signed so that the recipient can verify the token's authenticity.
- Compact: JWTs are compact, making them efficient to send in HTTP headers.
- Interoperability: As a JSON-based standard, JWTs are easy to use across different programming languages and platforms.
How JWT Bearer Token Authentication Works
Here's a step-by-step explanation of how JWT Bearer Token authentication typically works:
- Client Login: The client sends a login request with user credentials to the server.
- Server Verification: The server verifies the credentials. The server creates a JWT with the user's information if they are correct.
- Token Issuance: The server sends the JWT back to the client. This token is stored on the client side, usually in local storage or a cookie.
- Subsequent Requests: For each subsequent request, the client includes the JWT in the Authorization header as a Bearer token.
Authorization: Bearer <token>
- Token Verification: The server verifies the token's signature and checks the token's validity (expiration time, issuer, etc.). If valid, the server processes the request. If not, it returns an unauthorized error.
JWT Implementation Example:
Let's walk through the JWT token implementation in .NET 8.0 API using the Clean Architecture.
Solution and Project Setup:
First of all, set up DB and its objects, you can use the scripts shared under the AuthDemo.Infrastructure/Sql
folder of the code sample.
Once our back end is ready, Open Visual Studio 2022 and setup the required projects using the Clean Architecture, if you want to learn more about the Clean Architecture implementation please go through this article.
Set Up Core Layer: Under the solution, create a new Class Library project and name it AuthDemo.Core
.
- Add a new folder
Entities
and add a new entity class with the nameUser
.
Set Up Application Layer: Add another Class Library Project and name it AuthDemo.Application
.
- Add a reference to the
Core
project. - Add a new folder
Interfaces
and create a new interface and name it asIUserRepository
. - Also, create a new interface, and name it
IUnitOfWork
to implement Unit of Work.
Set Up Infrastructure Layer: Add a new Class Library Project and name it AuthDemo.Infrastructure
.
- Add the required packages to be used in this project.
Install-Package Dapper
Install-Package Microsoft.Extensions.Configuration
Install-Package Microsoft.Extensions.DependencyInjection.Abstractions
Install-Package System.Data.SqlClient
- Add the reference to projects (
Application
, andCore
), and add a new folderRepository
. - After that let’s implement the
IUserRepository
interface, by creating a new classUserRepository
. - Also, implement the
IUnitOfWork
interface, by creating a new classUnitOfWork
- Finally, register the interfaces with implementations to the .NET Core service container. Add a new class static
ServiceCollectionExtension
and add the RegisterServices method under it by injectingIServiceCollection
. - Later, we will register this under the API’s ConfigureService method.
Set up API Project: Add a new .NET 8.0 Web API project and name it AuthDemoApi
.
- Add the reference to projects (
Application
, andInfrastructure
), and add the below packages.
Install-Package Swashbuckle.AspNetCore
Install-Package Microsoft.IdentityModel.Protocols
Install-Package System.IdentityModel.Tokens.Jwt
Install-Package Microsoft.IdentityModel.JsonWebTokens
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
- Set up the
appsettings.json
file to manage the API settings and replace your DB connection string under theConnectionStrings
section.
"ConnectionStrings": {
//Update values in the connection string.
"DBConnection": "Data Source=localhost\\SQLEXPRESS; Initial Catalog=AuthDemoDB; Trusted_Connection=True;MultipleActiveResultSets=true"
}
- Add a secret key to verify and sign the JWT tokens.
"AppSettings": {
//Replace it with your secret key to verify and sign the JWT tokens, It can be any string.
"Secret": "8c8624e2-2afc-76a5-649e-9b9bf15cf6d3"
}
Configure Startup settings, such as RegisterServices (defined under the
AuthDemo.Infrastructure
project), and add the Swagger UI (withBearer
as the authentication scheme).Remove the default controller/model classes and add two classes (
AuthenticateRequest
andAuthenticateResponse
) under the Model folder, to handle API requests and responses.-
Add a
Helper
folder and add the below classes.-
AppSettings
- to map the the options fromappsettings.json
file. -
AuthorizeAttribute
- to validate the authorization. -
Common
- Add a GenerateJwtToken method to generate the JWT token. -
JwtMiddleware
- To validate the token and attach the user to context on successful Jwt validation.
-
-
Add a new controller and name it
UsersController
.- Implement
Authenticate
API to validate the user and generate the token. -
GetAll
API to return all users, and addAuthorize
attribute to put it behind the API security.
- Implement
Review the final project structure:
Run and Test API:
Run the project and test the API methods.
Running API without authentication throws a
401 - Unauthorizeed
error.
Authenticate the user and get a JWT token using the
Authenticate
API.
NOTE:
Check the source code here.
sandeepkumar17 / AuthDemoApi
NET 8.0 - Authentication API Sample using JWT Bearer Token
.NET 8.0 - Authentication API
Authentication API Sample using JWT Bearer Token in DOT NET 8.0
Blog
If you have any comments or suggestions, please leave them behind in the comments section below.
Top comments (1)
Thanks for share your knowledge.