I am developing an ASP.NET Core 2.2 Website where users need login and then use it.
The AccountController in my Website calls another ASP.NET Core WebApi (with [AllowAnonymous] attribute) to get the JWT token from username and password.
All controllers except for AccountController within the Website will have [Authorize("Bearer")] attribute to check if the user has been authorized.
My WebApi will have other controllers too which will require [Authorize("Bearer")], so the JWT token will be passed from the Website when making http requests. See below configured Startup.cs > ConfigureServices() method file in WebApi project:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidIssuer = "ZZZZ",
ValidAudience = "ZZZZ",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey))
};
});
services.AddAuthorization(auth =>
{
auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
});
And the Configure() method:
app.UseAuthentication();
ASP.NET Core WebApi - generate JWT token:
JWTToken jwt = new JWTToken();
jwt.Token = "";
jwt.Expires = DateTime.UtcNow.AddMinutes(90);
var claims = new[]
{
new Claim(ClaimTypes.UserData, UserId)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(privateSecretKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: "ZZZ",
audience: "ZZZ",
claims: claims,
expires: jwt.Expires,
signingCredentials: creds);
var tokenStr = new JwtSecurityTokenHandler().WriteToken(token);
jwt.Token = tokenStr;
return jwt;
I have completed the WebApi method to generate a token and return back a JWT token. But what do I do with that token so that the Authentication/Authorization works in my ASP.NET Core Website.
[HttpPost]
public async Task<IActionResult> Login(LoginModel model)
{
var httpClient = _httpClientFactory.CreateClient(ConstantNames.WebApi);
var response = await httpClient.PostAsJsonAsync($"{ApiArea}/authenticate", model);
if (response.IsSuccessStatusCode)
{
var jwtToken = await response.Content.ReadAsAsync<JWTToken>();
/* --> WHAT DO I DO HERE? <-- */
}
else
{
ModelState.AddModelError("Password", "Invalid password");
model.Password = "";
return View(model);
}
return RedirectToAction("Index", "Home");
}
So to make matters complex, the overview of my project is as such:
ASP.NET Core Website - has login page and other controllers with ajax calls for datatables and Forms for Edit pages which must be authorized ASP.NET Core WebApi - generated JWT token and has methods for other api calls which must be authorized
How do I tell the Website that if user is not Authorized, then go to my /Account/Login page?
Is this process correct, if not do I still need to add Identity and do this differently for Website?
await HttpContext.SignInAsync(...)await HttpContext.SignInAsync(...)but when I use it to create principal and pass it with some claims. The user does not signin, and is redirected to login page.