【发布时间】:2019-07-17 18:34:13
【问题描述】:
我正在开发一个 ASP.NET Core 2.2 网站,用户需要登录然后使用它。
我网站中的AccountController 调用另一个ASP.NET Core WebApi(带有[AllowAnonymous] 属性)从用户名和密码中获取JWT 令牌。
网站内除AccountController 之外的所有控制器都将具有[Authorize("Bearer")] 属性以检查用户是否已获得授权。
我的 WebApi 也会有其他需要 [Authorize("Bearer")] 的控制器,因此 JWT 令牌将在发出 http 请求时从网站传递。 WebApi项目中配置Startup.cs>ConfigureServices()方法文件见下:
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());
});
还有Configure() 方法:
app.UseAuthentication();
ASP.NET Core WebApi - 生成 JWT 令牌:
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;
我已经完成了生成令牌并返回 JWT 令牌的 WebApi 方法。但是我该如何处理该令牌,以便身份验证/授权在我的 ASP.NET Core 网站中工作。
[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");
}
为了让事情变得复杂,我的项目概述是这样的:
ASP.NET Core 网站 - 具有登录页面和其他控制器,其中包含对数据表和表单的 ajax 调用,必须获得授权 ASP.NET Core WebApi - 生成 JWT 令牌并具有用于其他必须授权的 api 调用的方法
我如何告诉网站如果用户未经授权,则转到我的/Account/Login 页面?
这个过程是否正确,如果不正确,我还需要添加身份并为网站做不同的事情吗?
【问题讨论】:
-
你可以只使用
await HttpContext.SignInAsync(...) -
WebAPI 通常返回 401 Unauthorized 响应并且不会重定向到登录页面,重定向必须在客户端或 MVC 控制器中完成。
-
@CamiloTerevinto 谢谢会试一试,我在哪里存储 jwt 令牌本身以供进一步的 API 调用,有内置的方法吗?
-
一种常见的方法是将其放入 Cookie 中,但请确保将其设置为安全
-
谢谢,我一直在尝试
await HttpContext.SignInAsync(...),但是当我使用它来创建主体并通过一些声明传递它时。用户未登录,并被重定向到登录页面。
标签: c# asp.net-core jwt