This series provides a concise guide on using JWT (JSON Web Tokens) to create tokens for authentication in an ASP.NET Core Web API.
1. Create a ASP.NET Core Web API Project
We'll be using Visual Studio 2019 with .NET Core 3.1.
2. Add JWT Services
2.1 Install the NuGet Package
Install System.IdentityModel.Tokens.Jwt via NuGet Package Manager.
2.2 Implement the JWT Service
public interface IJwtService
{
string GetToken(string name);
}
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace YourProject.AuthCenter.Utility
{
public class JwtService : IJwtService
{
private readonly IConfiguration _configuration;
public JwtService(IConfiguration configuration)
{
_configuration = configuration;
}
public string GetToken(string name)
{
// Claims (Payload)
// Claims contain essential information related to this token.
// Standard JWT fields:
// iss: Issuer of the token
// sub: Subject of the token
// exp: Expiration time (Unix timestamp)
// iat: Issued at time (Unix timestamp)
// jti: JWT ID
// aud: Audience
// nbf: Not Before (valid from time)
// Besides these, you can include any other JSON-compatible fields.
var claims = new[]
{
new Claim(ClaimTypes.Name, name),
new Claim("NickName", "NetCore"),
new Claim("Role", "Administrator")
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SecurityKey"]));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: _configuration["issuer"],
audience: _configuration["audience"],
claims: claims,
expires: DateTime.Now.AddMinutes(20), // 20-minute validity
signingCredentials: credentials
);
var tokenStr = new JwtSecurityTokenHandler().WriteToken(token);
return tokenStr;
}
}
}
2.3 Register the JWT Service
In the ConfigureServices method of Startup.cs, add:
services.AddScoped<IJwtService, JwtService>();
3. Add JWT Configuration to appsettings.json
Add the following configuration to your appsettings.json file:
"issuer": "http://localhost:9527",
"audience": "http://localhost:9527",
"SecurityKey": "4A9A70D2-B8AD-42E1-B002-553BDEF4E76F"
The SecurityKey can be a newly generated GUID.
4. Create an Authentication Controller
4.1 Install the Newtonsoft.Json NuGet Package
This is used for JSON serialization.
4.2 Controller Implementation
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using YourProject.AuthCenter.Utility;
namespace YourProject.AuthCenter.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private readonly ILogger<AuthController> _logger;
private readonly IConfiguration _configuration;
private readonly IJwtService _jwtService;
public AuthController(
IConfiguration configuration,
ILogger<AuthController> logger,
IJwtService jwtService)
{
_configuration = configuration;
_logger = logger;
_jwtService = jwtService;
}
[Route("Login")]
[HttpGet]
public string Login(string username, string password)
{
var result = VerifyLogin(username, password);
var token = result ? _jwtService.GetToken(username) : string.Empty;
return JsonConvert.SerializeObject(new
{
result,
token
});
}
private bool VerifyLogin(string username, string password)
{
return username == "admin" && password == "123456";
}
}
}
5. Run the Application
- Start the Web API project. In a browser, navigate to
https://localhost:5001/api/auth/Login(with out parametres). You should see:
{"result":false,"token":""}
- Next, navigate to
https://localhost:5001/api/auth/Login?username=admin&password=123456. You should receive a response similar to:
{"result":true,"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJOaWNrTmFtZSI6Ik5ldENvcmUiLCJSb2xlIjoiQWRtaW5pc3RyYXRvciIsImV4cCI6MTYxMzk1OTM0NSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo5NTI3IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo5NTI3In0.JdkUR3MV2uC8dQAnqzskFreVFdrHK4WTRrMJSDm7STY"}
This token can now be used for subsequent authenticated requests.