[英]ASP.NET Core Website to WebApi authentication using JWT token
我正在开发一个ASP.NET Core 2.2网站,用户需要登录然后才能使用它。
我的网站中的AccountController
调用另一个ASP.NET Core WebApi(具有[AllowAnonymous]
属性)从用户名和密码获取JWT令牌。
除了网站内的AccountController
之外的所有控制器都将具有[Authorize("Bearer")]
属性来检查用户是否已被授权。
我的WebApi也会有其他控制器,需要[Authorize("Bearer")]
,因此在发出http请求时,JWT令牌将从网站传递。 请参阅下面在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;
我已经完成了WebApi方法来生成令牌并返回一个JWT令牌。 但是我该如何处理该令牌,以便身份验证/授权在我的ASP.NET核心网站中运行。
[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核心网站 - 具有登录页面和其他控制器,其中包含用于数据表的ajax调用和用于编辑页面的表单,这些页面必须经过授权ASP.NET Core WebApi生成的JWT令牌,并具有必须授权的其他api调用的方法
如何告知网站如果用户未获得授权,请转到我的/Account/Login
页面?
这个过程是否正确,如果不是,我仍然需要添加身份并为网站做不同的事情吗?
如果您的ASP.NET核心网站和ASP.NET Web API是两个不同的网站:
Authorization : Bearer {access_token}
的标头来发送请求。 或者如果您想通过cookie / querystring发送它,请注册OnMessageReceived
处理程序 我不确定您的身份验证是怎样的。
假设您选择为ASP.NET核心网站使用cookie,请确保您已设置LoginPath = "/Account/Login";
// the Startup::ConfigureServices of your ASP.NET Core Website
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(o => {
o.LoginPath = "/Account/Login";
});
然后根据Camilo Terevinto的建议,您需要在以下位置签署用户:
[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>();
var username = ...
var others = ...
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, username),
// add other claims as you want ...
};
var iden= new ClaimsIdentity( claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(iden);
await HttpContext.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, principal);
return Redirect("/")
}
else
{
ModelState.AddModelError("Password", "Invalid password");
model.Password = "";
return View(model);
}
return RedirectToAction("Index", "Home");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.