0

I'm building .NET 5 MVC Project and I am trying to implement JWT based Authentication.

I am able to get the user Username and Password, validate if it exist in the database and create a valid JWT token string, but after this I don't know how to actually save the token into the browser, so that I can authenticate and authorize later on.

I am unable to access controllers that use the [Authorize] attribute.

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    //Skipping code for clearence
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = Configuration["Jwt:Issuer"],
                ValidAudience = Configuration["Jwt:Audience"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
            };
        });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //Skipping code for clearence
    app.UseAuthentication();
    app.UseAuthorization();
}

appsettings.json

{
  "Jwt": {
    "Key": "SomeKey",
    "Issuer": "SomeIssuer",
    "Audience": "SomeIssuer"
  }
}

CreateToken method in one of my classes, which it works and generates valid JWT Token string

public string CreateToken(User user, string roleName)
{
    const int EXPIRY_DURATION_MINUTES = 120;

    var claims = new[] {
        new Claim(ClaimTypes.Name, user.UserName),
        new Claim(ClaimTypes.Role, roleName),
        new Claim(ClaimTypes.NameIdentifier,
        Guid.NewGuid().ToString())
    };

    var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));

    var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);

    var tokenDescriptor = new JwtSecurityToken(_configuration["jwt:Issuer"], _configuration["Jwt:Audience"], claims,
        expires: DateTime.Now.AddMinutes(EXPIRY_DURATION_MINUTES), signingCredentials: credentials);

    return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
}

SignIn action in my Account controller. What I am trying to achieve is to store the token in the browser and use the default authentication and role based authorization behaviour of .NET 5

[HttpPost]
public async Task<IActionResult> SignIn(SignInUserRequestModel request)
{
    try
    {
        var token = await _authenticationService.SignInUser(request);
              
        HttpContext.Response.Headers.Add("Authorization", $"Bearer {token}");

        return Ok(token);
    }
    catch (ArgumentException exception)
    {
        return BadRequest(new { Code = 400, Message = exception.Message });
    }            
}
Sovak
  • 373
  • 1
  • 5
  • 17
  • Your action is and api action? You should use javascript ajax to call and get the token and store it. MVC can write a cookie with the token inside that is another option. – AliK Jul 18 '21 at 21:06
  • I am not using an api controller I am building MVC project and I just want to store the Token somehow so I can use the `[Authorize]` attribute without the need to use javascript. If it's possible to store the JWT token with a cookie, please provide me with code sample. – Sovak Jul 18 '21 at 21:16
  • See if [this](https://stackoverflow.com/questions/61427818/store-validate-jwt-token-stored-in-httponly-cookie-in-net-core-api) helps. I have not checked the answer but just found it and should point you in the direction. – AliK Jul 18 '21 at 21:19
  • Hi @Sovak, please check [this answer](https://stackoverflow.com/a/68373376/11398810) if it helps you. – Rena Jul 19 '21 at 07:52
  • @Rena Yes, this works. I guess there is no way to actually set the `Authorization Header` for the browser you need to implement different logic for the Authentication. Don't know how to mark that the link to the post you provided is a solution. – Sovak Jul 19 '21 at 16:50
  • Hi @Sovak, I have post as an answer below. – Rena Jul 20 '21 at 01:21
  • Not sure why community deletes my answer below. The shared link is also answered by myself which it is not marked by that op. Maybe you could share your demo and mark yourself to help others. – Rena Jul 20 '21 at 05:13

0 Answers0