Json web token which is also known as JWT is an international standard which is used to transfer data securely over internet for various purposes. Fore example you can use JWT token for authenticate and authorization in web APIetc. Here in this blog post, we will explore JWT token based authentication in web api step by step.
Authenticate ASP.NET Core Web API with JWT Token
Getting StartedImplementing JWT Json web token in C# or asp.net core is very easy process, here we will demonstrate the following points for securing web API.
- Download Json Web Token (JWT).
- Add JWT web token keys into configuration settings.
- Register or configure JWS Token in project.
- Generate a JWT token.
- JWT authentication in action.
- Enable Swagger for JWT Token Fields.
- Decode JWT.
Download Json Web Token (JWT)
The JWT can be downloaded from Microsoft NuGet package. The below steps guide to download.
- Go to your Solution Explorer and right click on the solution Explorer.
- Click on the NuGet Package Manager and type jsonwebtoken in the search box of Browse tab.
- List if libraries will be listed, select Microsoft.AspNetCore.Authentication.JwtBeare.
- Click on the Install button on the right side of the pan.
Add JWT web token keys into configuration settings
Open the appsettings.json file, add the below settings at the end of the file by copying and pasting. These settings are JWTsecret and will help you to generate or decode tokens.
,
"JWT": {
"Key": "Yh3k7QSu4l8CZg5p6X3Pna9L0Miy4D3Bvt0JVr87UcOj69Kqw5R2Nmf4FWs03Hdx",
"Issuer": "JWTAuthenticationServer",
"Audience": "JWTServicePostmanClient",
"Subject": "JWTServiceAccessToken"
}
Json Web Signature
Register or configure JWS Token in project
After adding keys in appsetting.json file for token, we need to register the JWT into project. To do this, we need to register a JWT authentication schema by using "AddAuthentication" method. The below codes describe, how to configure JWT authentication into project.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
};
});
Using JWT for API Authentication
Generate a JWT token
The following code in signin method(one of the endpoint of api used to signin user and responsed token) describes how to generate token. The token will be generated as string and this string value will be sent to the client as response.
[HttpPost("signin")]
public string Signin(Credential credential)
{
if (credential != null)
{
Guid guid = Guid.NewGuid();
string token = guid.ToString();
int result = this.userAccess.Signin(credential, token);
if (result > 0)
{
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(this.configuration["JWT:Key"]));
var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
List<Claim> claims = new List<Claim>();
claims.Add(new Claim("User", credential.UserName));
claims.Add(new Claim("UserType", result.ToString()));
claims.Add(new Claim("token", token));
claims.Add(new Claim("Subject", this.configuration["JWT:Subject"]));
var tokeOptions = new JwtSecurityToken(issuer: this.configuration["JWT:Issuer"], audience: this.configuration["JWT:Audience"], claims: claims, expires: DateTime.Now.AddMinutes(6), signingCredentials: signinCredentials);
var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);
return tokenString;
}
else
return "Invalid user";
}
else
return "Invalid credential";
}
JWT Authentication in action
To authenticate an endpoint before invoking by router, add the [Authorize] attribute above the action of controller like below.
[Authorize(AuthenticationSchemes = Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme)]
public Profile GetProfile()
{
}
JWT Authentication Token Example
In the above code, when cliet reqests to GetProfile API, the rauter first will verify whether the token is exists with reqest header or not. If the token not available in request then routher will throw with 402 response code.
Swagger JWT Token Authentication
By default the JWT token field will appear in the swagger. after adding above configuratation, we need to add below codes for jwt standard fields. Find the builder.Services.AddSwaggerGen() in the programm file and replace with below code.
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "FMN", Version = "v1" });
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{
Name = "Authorization",
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer",
BearerFormat = "JWT",
In = ParameterLocation.Header,
Description = "JWT Authorization header using the Bearer scheme."
});
});
Swagger Authorization
JWT Token Decode
The following code are for JWT token dectypion. The jwt.decode method only decodes the token and should only every be used on trusted messages. Since jwt.verify also decodes the token after verification, it provides a safer and more secure way to decode the token, so it should be the preferred method.
void JWTDecode()
{
var handler = new JwtSecurityTokenHandler();
//jwt io
var token = Request.Headers["Authorization"].ToString().Replace("Bearer ", string.Empty);
//Request.Headers["Authorization"];
//jwtsecretKey
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(this.configuration["JWT:Key"]));
var validations = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = secretKey,
ValidIssuer = this.configuration["JWT:Issuer"],
ValidAudience = this.configuration["JWT:Issuer"]
};
////jwt io :JWT token decode
JwtSecurityToken jwtSecurityToken = handler.ReadJwtToken(token);
}
JWT Structure
Header
JWT Header identifies which algorithm is used to generate the signature. You may notice JWT HS256 in Signin method is used which indicates that this token is signed using HMAC-SHA256.
Payload
JWTPayload contains the claims, the claims are additional data that can kept with token. Ther are three types of claims those are registered, public and private claims.
Signature (JSON Web Sugbatyre)
Securely validates the token. The signature is calculated by encoding the header and payload using Base64url Encoding RFC 4648 and concatenating the two together with a period separator. That string is then run through the cryptographic algorithm specified in the header.
SummaryHere in thi blog post, we learned to secure web api with jwt token in C# by using JWT for api authenticatioN and Authorization in API as well as web applications. I hope the above of this blog post will be helpful to you.
Thanks