I'm trying to add authentication to my app, frontend VueJS backend Asp.NET core 2.1 but I'm failing to get it to actually authenticate in the end.
Setting up the authentication in Asp.NET:
var key = Encoding.ASCII.GetBytes("mysecret");
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
var userService = context.HttpContext.RequestServices.GetRequiredService<IUserService>();
var userId = int.Parse(context.Principal.Identity.Name);
var user = userService.GetById(userId);
if (user == null)
{
// return unauthorized if user no longer exists
context.Fail("Unauthorized");
}
return Task.CompletedTask;
}
};
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
// configure DI for application services
services.AddScoped<IUserService, UserService>();
My UserService is mocked to return the same hardcoded user always.
The frontend seems to be sending the correct token it gets from the backend when logging in:
But, I'm still getting rejected when calling authorized endpoints:
The server reports the following logs:
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
Executing ChallengeResult with authentication schemes ().
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[2]
Successfully validated the token.
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[12]
AuthenticationScheme: Bearer was challenged.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action DnaBackend.Controllers.DnaController.UploadFile (DnaBackend) in 32.891ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 41.847ms 401
info: Microsoft.AspNetCore.Server.Kestrel[32]
Connection id "0HLIDVBUA1Q5P", Request id "0HLIDVBUA1Q5P:00000003": the application completed without reading the entire request body.
Any ideas why this is failing? I'm using CORS too, if that makes any difference(?).
Login endpoint looks like so:
[HttpPost("login")]
public IActionResult Login([FromForm]LoginRequest loginRequest)
{
var user = _userService.Authenticate(loginRequest.Username, loginRequest.Password);
if (user == null)
return BadRequest(new { message = "Username or password is incorrect" });
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, user.Id.ToString())
}),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
// return basic user info (without password) and token to store client side
return Ok(new LoginResponse(user.Id, user.Username, user.FirstName, user.LastName, tokenString));
}
In my case it was that i had put UseAuthorization
before UseAuthentication
.
Please make sure these methods are in the following order:
app.UseAuthentication();
app.UseAuthorization();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With