How to Implement Secure JWT Authentication in ASP.NET Core Minimal APIs?

July 12, 2024

ASP.NET Core offers a simplified hosting model called minimal APIs that allows developers to build lightweight APIs with minimal dependencies. These minimal APIs are particularly ideal for constructing microservices and fast HTTP APIs, making them a popular choice in modern development. Naturally, securing the endpoints of such APIs is crucial to ensure that only authorized users can access sensitive data and operations. One of the most effective methods to implement this security is through JSON Web Tokens (JWT). JWT authentication and authorization can be seamlessly integrated into ASP.NET Core minimal APIs, ensuring robust security measures. This article will provide a detailed, step-by-step guide on how to implement JWT authentication in an ASP.NET Core minimal API application, ensuring your APIs are secure and reliable.

1. Initiate a Minimal API Application in Visual Studio 2022

The first step in securing your ASP.NET Core minimal API using JWT authentication is to create a new minimal API project in Visual Studio 2022. This process establishes the foundation upon which you will build and secure your API endpoints. Begin by launching the Visual Studio 2022 IDE and selecting the “Create new project” option. In the “Create new project” window, choose the “ASP.NET Core Web API” template from the list provided.

After selecting the template, click “Next” and fill in the necessary details in the “Configure your new project” window, such as the name and location of your new project. If you prefer to keep things organized, you can check the “Place solution and project in the same directory” checkbox, but this step is optional. Next, click “Next” to proceed to the “Additional Information” window. Here, uncheck the “Use controllers…” checkbox because you will be using minimal APIs in this example. Confirm that the “Authentication Type” is set to “None” (default), and ensure the checkboxes for “Enable Docker,” “Configure for HTTPS,” and “Enable Open API Support” are all unchecked, as these features are not required for this specific example. Finally, click “Create” to generate your ASP.NET Core Web API project.

2. Develop an API Endpoint in the Program.cs File

With your minimal API project created, the next step is to develop an API endpoint in the Program.cs file. When you create a new minimal Web API project in Visual Studio 2022, a Program.cs file is automatically generated with a few lines of default code. You need to modify this default code to set up a simple HTTP GET endpoint that you will later secure with JWT authentication.

Replace the default code in Program.cs with the following code snippet to create a basic API endpoint:

“`csharp
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet(“/security/getMessage”, () => “Hello World!”).RequireAuthorization();
app.Run();
“`

In this snippet, the `MapGet` method is used to create a new endpoint at `/security/getMessage` that returns a simple “Hello World!” message. The `RequireAuthorization` method is particularly important as it enforces the need for authorization to access this endpoint. This ensures that the endpoint is protected and requires valid authentication information. If someone attempts to call this endpoint without providing the necessary authentication details, they will encounter an HTTP 401 Unauthorized error.

3. Incorporate the Microsoft.AspNetCore.Authentication.JwtBearer NuGet Package into the Project

To implement JWT authentication, you need to add the necessary dependencies to your project. The `Microsoft.AspNetCore.Authentication.JwtBearer` NuGet package provides the core functionality required for JWT authentication in ASP.NET Core. To add this package, navigate to the Solution Explorer window in Visual Studio, right-click on your project, and select “Manage NuGet Packages.”

In the NuGet Package Manager window, search for the `Microsoft.AspNetCore.Authentication.JwtBearer` package and install it. Alternatively, you can install the package using the NuGet Package Manager console by entering the following command:

“`bash
PM> Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
“`

Once the package is installed, your project is equipped with the necessary tools to handle JWT authentication. This package facilitates the token validation process, enabling your application to authenticate and authorize users based on JWT.

4. Apply JWT Authentication Settings in the Program.cs File

After incorporating the JwtBearer package, the next step is to configure JWT authentication settings in the Program.cs file. This configuration specifies how your application should handle authentication and token validation at runtime. Start by adding the relevant namespaces at the top of your Program.cs file:

“`csharp
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
“`

Next, configure the authentication settings within the `WebApplicationBuilder` object. This is done by calling the `AddAuthentication` method and specifying JwtBearer as the default authentication scheme:

“`csharp
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
o.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = builder.Configuration[“Jwt:Issuer”],
ValidAudience = builder.Configuration[“Jwt:Audience”],
IssuerSigningKey = new SymmetricSecurityKey
(Encoding.UTF8.GetBytes(builder.Configuration[“Jwt:Key”])),
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = false,
ValidateIssuerSigningKey = true
};
});
“`

In this configuration, the `TokenValidationParameters` instance specifies the parameters your application will use to validate JWTs. The `Issuer`, `Audience`, and `Key` values are read from the appsettings.json file, ensuring that tokens are correctly validated against these settings.

5. Establish a User Model Class Named User to Store User Login Credentials

To proceed with JWT authentication, you need a user model class to store login credentials. This class will be used to accept and validate user credentials when generating and validating tokens. Create a new file named `User.cs` in your project and add the following code:

“`csharp
public class User
{
public string UserName { get; set; }
public string Password { get; set; }
}
“`

This `User` class contains two properties, `UserName` and `Password`, which represent the user’s login details. These properties will be used to validate the user’s identity and generate JWTs upon successful authentication. Creating this model helps to manage and store user credentials effectively within your application.

6. Define a Secret Key in the appsettings.json File

A critical aspect of JWT authentication is the secret key, which is used to sign and validate tokens. Defining this key in the appsettings.json file helps manage these values securely and makes them easily configurable. Open your appsettings.json file and add a new section called `Jwt` with the following JSON structure:

“`json
“Jwt”: {
“Issuer”: “https://yourdomain.com/”,
“Audience”: “https://yourdomain.com/”,
“Key”: “This is a sample secret key – please don’t use in production environment.'”
}
“`

Replace the values of `Issuer`, `Audience`, and `Key` with appropriate values for your application. The `Key` should be a strong and unique string, ideally stored securely and not exposed in the source code for production environments. These values will be used later in the token generation and validation process to ensure tokens are correctly signed and verified.

7. Configure JWT Authentication Parameters in the Program.cs File

After defining the secret key, you need to configure JWT authentication parameters in the Program.cs file. The `TokenValidationParameters` class plays a crucial role in this configuration by specifying how tokens should be validated. Continuing from the previous setup, ensure your authentication configuration in Program.cs includes the following:

“`csharp
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
o.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = builder.Configuration[“Jwt:Issuer”],
ValidAudience = builder.Configuration[“Jwt:Audience”],
IssuerSigningKey = new SymmetricSecurityKey
(Encoding.UTF8.GetBytes(builder.Configuration[“Jwt:Key”])),
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = false,
ValidateIssuerSigningKey = true
};
});
“`

Here, the `TokenValidationParameters` instance reads the `Issuer`, `Audience`, and `Key` values from the appsettings.json file. These parameters help ensure that the JWTs your application receives are valid and correctly signed. The `ValidateIssuer`, `ValidateAudience`, `ValidateLifetime`, and `ValidateIssuerSigningKey` properties indicate whether these aspects of the token should be validated, providing additional security checks during the authentication process.

8. Add Authorization Services Middleware to the Application in the Program.cs File

With authentication settings in place, the next step is to add the authorization services middleware to your application. This middleware ensures that all requests are processed with the appropriate authentication and authorization checks. Add the following code to your Program.cs file:

“`csharp
builder.Services.AddAuthorization();
app.UseAuthentication();
app.UseAuthorization();
“`

The `AddAuthorization` method registers the authorization services with the DI container. The `UseAuthentication` and `UseAuthorization` methods enable the authentication and authorization middleware in the request pipeline. This setup ensures that requests to your API are checked for valid authentication tokens and that only authorized users can access protected endpoints.

9. Generate and Validate the JSON Web Token in the Program.cs File

After adding the JwtBearer package, the next crucial step is to set up JWT authentication settings in the Program.cs file. This setup dictates how your application will manage authentication and token validation during runtime. Begin by including the necessary namespaces at the top of your Program.cs file:

“`csharp
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
“`

You then configure the authentication settings within the `WebApplicationBuilder` object. This is achieved by invoking the `AddAuthentication` method and defining JwtBearer as the default authentication scheme:

“`csharp
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
o.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = builder.Configuration[“Jwt:Issuer”],
ValidAudience = builder.Configuration[“Jwt:Audience”],
IssuerSigningKey = new SymmetricSecurityKey
(Encoding.UTF8.GetBytes(builder.Configuration[“Jwt:Key”])),
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = false,
ValidateIssuerSigningKey = true
};
});
“`

In this setup, the `TokenValidationParameters` indicates how your application will validate JWTs. The values for `Issuer`, `Audience`, and `Key` are pulled from the appsettings.json file, ensuring tokens are authenticated correctly according to these parameters. This configuration guarantees your application handles JWT authentication securely and effectively, validating tokens based on the issuer, audience, and a signing key.

Subscribe to our weekly news digest!

Join now and become a part of our fast-growing community.

Invalid Email Address
Thanks for subscribing.
We'll be sending you our best soon.
Something went wrong, please try again later