Home > Software design >  .NET6- Login User using JWT token
.NET6- Login User using JWT token

Time:06-24

I have two projects one client-side in MVC and the second a Web API project, both are in .Net 6.

Web API side
I want to Authenticate users coming to the client side. I know that to add authentication to Web API most recommended way is a JWT token. So I added the below code to my Web API program.cs class to use JWT authentication.

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
    options.RequireHttpsMetadata = false;
    options.SaveToken = true;
    options.TokenValidationParameters = new TokenValidationParameters()
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidAudience = builder.Configuration["Jwt:Audience"],
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
    };
});    

Next, I added a login method as below in the Web API that simply generates the JWT token and returns the token. Not adding GenerateToken() code to keep things simple

[HttpGet]
[Route("login")]
public JsonResult Login()
{
    var token = TokenHelper.GenerateToken();

    return new JsonResult(new { token = token });
}    

Client-side
On the client-side, I have configured cookie authentication which checks if the user is not authenticated, it will redirect the user to the login page on the client-side

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
   .AddCookie(options =>
    {
        options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
        options.SlidingExpiration = true;
        options.AccessDeniedPath = "/Error/Forbidden/";
        options.LoginPath = "/home/login/";
    });    

On the login page, I ask the user to enter their username and password and then call the login endpoint in the Web API project that issues a token. I successfully get the token.

using (var client = new HttpClient())
{
      client.BaseAddress = new Uri("https://localhost:7157/");

      HttpResponseMessage response = await client.GetAsync("WeatherForecast/login");

      if (response.IsSuccessStatusCode)
      {
         var token= await response.Content.ReadFromJsonAsync<TokenModel>();
      }
      else
      {
         Console.WriteLine("Internal server Error");
      }
}

Now, this is the point where I am struggling. I want to sign in user using this token on the client-side something like generate a cookie using token or use HttpContext.SignInAsync to sign in the user. I have the token but not sure what is the best practice to log in the user or how to use that token.

CodePudding user response:

If you want cookie authentication(as you setted in your MVC project),you could use ReadToken() method to read the claims inside the token, and generate the ClaimsIdentity which is required in HttpContext.SignInAsync()method

                var jsonToken = new JwtSecurityTokenHandler().ReadToken(token) as JwtSecurityToken;
                var username = jsonToken.Claims.FirstOrDefault(m => m.Type == ClaimTypes.Name).Value;
                 .............
                 //add other logic
                if (username==user.Name)
                {
                    var claims = new Claim[]
                    {
                    new Claim(ClaimTypes.Name, user.Name),
                     };
                    var claimsIdentity = new ClaimsIdentity(claims);
                    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
                }

if you want JWT Authentication in your MVC project,you could set as below :

services.AddAuthentication(options =>
            {
                
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            
            .AddJwtBearer(options =>
             {
                 options.TokenValidationParameters = new TokenValidationParameters
                 {
                     ......
                 };
                 options.Events = new JwtBearerEvents
                 {

                     OnMessageReceived = context =>
                     {
                         var accessToken = context.Request.Cookies["token"];
                         
                         if (!string.IsNullOrEmpty(accessToken))
                         {
                             context.Token = accessToken;
                         }

                         return Task.CompletedTask;
                     }
                 };

add the token in your login controller:

Response.Cookies.Append("token", token);
  • Related