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.
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.
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