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 });
}
}