ASP.NET Core 2 - Angular & JWT Authentication


ASP.NET Core 2 - Angular & JWT Authentication



Problem: I seem unable to fetch the User or any user-related data (e.g. UserID) in any controller after the token has been recorded to browser local storage.


User


UserID



I've set a breakpoint and studied HttpContext member of ControllerBase instance (the client app makes request + the auth_token is kept in local storage at this stage).


HttpContext


ControllerBase


auth_token



You only can extract the referrer url from Headers but there's no info about tokens.


Headers


tokens



Even if you create a cookie for the token - the Request doesn't have it (0 cookies found at all).


Request



Perhaps I misunderstand the concept of how authorization works.



Here's the bit I misunderstand most - how does ASP.NET Core fetch the token from the request made by client app - it must be kept in headers?


ASP.NET Core


token



Also, could anyone share a working example of JWT Authentication where Angular & ASP.NET Core are separate solutions?


Angular


ASP.NET Core






I've implemented login functionality and I store the access token in browser local storage.


this._authService.authenticate(this.loginModel)
.finally(finallyCallback)
.subscribe((result: AuthenticateOutput) => {
localStorage.setItem('auth_token', result.token);
});



Must the name of the token be in accordance with any conventions? (I wonder if auth_token is appropriate in this case.)


auth_token



SessionController - the method which fetches current user info:


SessionController


public async Task<GetCurrentLoginDetailsOutput> GetCurrentLoginDetails()
{
var output = new GetCurrentLoginDetailsOutput();
var user = await UserManager.GetUserAsync(HttpContext.User);
if (user != null)
{
output.User = Mapper.Map<UserDto>(user);
output.Tenant = Mapper.Map<TenantDto>(user.Tenant);
}
return output;
}



In my Authenticate method of AuthContoller I create Claim which holds UserID:


Authenticate


AuthContoller


var user = await _userService.Authenticate(input.UserName, input.Password);

var tokenDescriptor = new SecurityTokenDescriptor
{
Issuer = _config.GetValidIssuer(),
Audience = _config.GetValidAudience(),
SigningCredentials = new SigningCredentials(_config.GetSymmetricSecurityKey(), SecurityAlgorithms.HmacSha256),
Subject = new ClaimsIdentity(new
{
new Claim("id", user.Id.ToString())
})
};



_userService.Authenticate method fetches the user and checks if the password is correct as follows:


_userService.Authenticate


var user = _context.Users.SingleOrDefault(x => x.UserName == username);

if (user == null) { return null; }

bool correctPassword = await UserManager.CheckPasswordAsync(user, password);



JWT config in Startup.cs


Startup.cs


services
.AddAuthentication()
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters()
{
IssuerSigningKey = Configuration.GetSymmetricSecurityKey(),
ValidAudience = Configuration.GetValidAudience(),
ValidIssuer = Configuration.GetValidIssuer()
};
});



CORS is configured as follows:


CORS


.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()






Additional info:



The Angular app is a separate solution / project - not the "one solution" template available in VS2017.


VS2017



I'm using ASP.NET Core v2.1


ASP.NET Core v2.1



I'm using NSwag.AspNetCore package to auto-generate services for Angular project.



Here's the tutorial which I've been using to code my app.





Typically the JWT would be sent to the backend either in a cookie, or in a header, yes. In the example you've linked to, they send it in the "Authorization" header
– user184994
Jun 30 at 18:16






Why does your method have [AllowAnonymous] if you need user data at that point?
– Alex Riabov
Jun 30 at 18:18





good point @AlexRiabov, will investigate this bit, thank you!
– Alex Herman
Jun 30 at 18:19









By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

List of Kim Possible characters

Audio Livestreaming with Python & Flask

NSwag: Generate C# Client from multiple Versions of an API