Simple JWT Authentication using ASP.NET Core Web API

Meghna
8 min readOct 31, 2023

--

This is a step-by-step tutorial on implementing JWT Authentication using ASP.NET Core Web API. We won’t be using any additional Data Base Connection and will define the user credentials in the code for simplicity.

JWT Authentication is a popular method to provide authentication while exchanging data between two parties. It is a token-based stateless authentication mechanism. JWT is mostly used for API authentication and server-to-server authentication.

Step 1: Create a new Project

Start Visual Studio 2022

Create a new Project

Select ASP.NET Core Web API and click on Next

Enter the project name and Location as per your preference and click on Next

Select the framework (I’ve used .NET 7.0) and click on Create

You’ll get a default Web API Project. You can delete the default WeatherForecastController.cs and WeatherForecast.cs to avoid any sort of confusion.

Step 2: Manage NuGet Packages

From Solution Explorer, right-click on the Dependencies and select “Manage Nuget Packages”

A NuGet Package Manager Window will be opened. Click on Browse and Search JWTBearer, and you’ll get the results. From results select Microsoft.AspNetCore.Authentication.JwtBearer and click on install.

From the License Acceptance Dialog Box, click on “I Accept” and the installation will be started.

Step 3: Start Coding :-)

In order to apply JWT Authentication, we have to provide a key for JWT to work. This key will be used every time to provide a token upon successful login from the user.

The key can be anything — It can be your name, any other significant text or number in your project or you can also provide any randomly generated hash value.

I’ve used a random MD5 Hash generator online tool that provides 10 random hash values by default, you can select any one value from this, or you can also change the number of hash values generated from the settings provided.

Now, open the appsettings.json file and add a section for JWT key

Please change the key value as per your preference
"Jwt": {
"Key": "3713ab7f791c1991d3a210c5fa68c3aa"
},

When the user tries to access the API, we have to take the user credential as input and use it further to authenticate the user. To achieve this, we will create a user model class consisting of a Username and Password and store the input from the user in this model class.

To create a user model class, right-click on the project name -> Add -> Class, and a new window will appear, select “class” and give an appropriate name (e.g. User.cs) and click on “Add”

We have to create two properties for user authentication — UserName and Password, which can be done as below:

namespace JWT_Authentication
{
public class User
{
public string UserName { get; set; }
public string Password { get; set; }
}
}

Now, we have to write the actual code for Implementing JWT Authentication and returning the token after validating the user.

For this, you can create a Folder by right-clicking on the project name and selecting “Add new folder”. We will be naming this folder “Services”.

After the Services Folder is created, we have to add a service and an interface to implement this service. In order to do that, we have to right-click on the Services folder -> Add -> New Item -> Select Interface -> Give a name for this interface -> Add

This interface will be implementing the Login Service and we need to pass the User model to this interface. We are returning the token from the service so we will be keeping the return type as string.

namespace JWT_Authentication.Services
{
public interface IUserService
{
string Login(User user);
}
}

For the next step, we have to add a UserService File in the Services Folder. To do this, we have to right-click on Services -> Add -> Class, a new class dialog box will appear, here we have to name the service “UserService. cs” and click on “Add”

In this UserService.cs, we have to implement the JWT functionality.

  1. You will get the following code generated by default in UserService.cs. Here, we have to implement the IUserService.cs interface.
namespace JWT_Authentication.Services
{
public class UserService
{
}
}

2. Hover over the IUserService and click on “Implement interface”.

3. Create a new List of User Class Model to assign a UserName and Password against which the incoming user request will be validated. You can change the UserName and Password according to your preference.

4. In order to access the JWT Key from the appsettings.json, we have to inject the Configuration as below:

5.

  1. The login user will check whether the incoming data matches the predefined credentials i.e. “Admin” and “Password” in this case.
  2. If the loginUser is null, it means the credentials are different and it will return an empty string.
  3. If loginUser contains some value, we will generate a new JwtTokenHandler and assign it to tokenHandler.
  4. We will access the JWT key from appsettings and store it in a variable named key.
  5. We will create a new token descriptor where we will assign the UserName as a claim.
  6. We have to assign the Expiry time, which can be set as per your preference.
  7. Using the appropriate Security Algorithm, new signing credentials will be created
  8. Using the token descriptor parameter, we will create a new token.
  9. Store this token in a variable and return it upon successfully validating the user.
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace JWT_Authentication.Services
{
public class UserService : IUserService
{
private List <User> _users = new List<User>
{
new User{ UserName = "Admin", Password = "Password"}
};

private readonly IConfiguration _configuration;

public UserService(IConfiguration configuration)
{
_configuration = configuration;
}

public string Login(User user)
{
var LoginUser = _users.SingleOrDefault(x => x.UserName == user.UserName && x.Password == user.Password);

if(LoginUser == null)
{
return string.Empty;
}

var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_configuration["Jwt:Key"]);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, user.UserName)
}),
Expires = DateTime.UtcNow.AddMinutes(30),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
string userToken = tokenHandler.WriteToken(token);
return userToken;
}
}
}

To register the service, we have to add the following line of code in Program.cs

builder.Services.AddScoped<IUserService, UserService>();

6. In order to implement the service we have just created, we will create a controller, which will take the user credentials as input and provide the token.

To create a new controller, right-click on the controllers folder -> Add -> Controller. From the controller dialog box, select API Controller — Empty Controller -> Add. Let’s name this controller “UserController.cs” and then click on Add.

7. In the newly created User Controller, we must inject the service as we have to use the UserService. Then, we will create a new Login Method which has to use the [AllowAnonymous] attribute, as this method will be passing the token and should be accessible to anyone to access the token.

  1. Injecting the UserService.
  2. Specifies the “Post” request and uses “Login” as the route.
  3. Passing the User model as a parameter to the Login Method.
  4. Calling the Login method of User Service and passing the user model as a parameter.
  5. If the Service returns null or empty, it did not find the matching credentials to validate.
  6. Returning token upon successfully authenticating the user.
using JWT_Authentication.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace JWT_Authentication.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
private readonly IUserService _userService;
public UserController(IUserService userService)
{
_userService = userService;
}

[HttpPost("Login")]
[AllowAnonymous]
public IActionResult Login(User user)
{
var token = _userService.Login(user);
if(token == null || token == string.Empty)
{
return BadRequest(new { message = "UserName or Password is incorrect" });
}
return Ok(token);
}
}
}

8. After completing this, run the solution. A swagger page will be opened in your default browser. We can use this swagger to test our API endpoints.

Expand the “/api/User/Login” Post request that would be visible in Swagger and click on “Try it out”. Enter your credentials, the ones that we have mentioned while creating the UserService (in this case UserName = “Admin” and Password = “Password”) and click on “Execute”.

In the response body, we will get the Token that can be used to access any other endpoints that contain some sensitive data and that needs to be Authorized.

In this way, we have implemented the JWT Authentication using ASP.NET Core and have received the token upon successful authentication of user. Here is the source code link for reference:

--

--

Meghna

Dedicated software sorcerer conjuring elegant solutions in the language of code.