两个单独的项目,都是DotNet Core 3:API和Web MVC。
MVC和移动应用程序都仅与API通讯。
MVC需要通过API对用户进行身份验证(并且还必须具有Google身份验证,才能传递给API),这是通过使用登录页面完成的,该页面提交到mvc上的/ account / login /向API打开一个httpclient请求,该请求返回JWT令牌。该API将使用JWT进行Web MVC应用程序中的所有其他操作。
不幸的是,那里的许多文档仅涉及API返回令牌或使用SPA框架进行身份验证。我正在考虑将MVC用作客户端。
遇到一些问题访问了返回的JWT的声明,并研究了如何将其存储在MVC应用程序使用的身份验证Cookie中。
API身份验证控制器 / Auth /
public IActionResult Post()
{
//Do auth check here
if (Request.Form["username"] == "test@test.com" && Request.Form["password"] == "test")
{
var authClaims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, "testUsername"),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, "ID"),
new Claim("Name", "testName"),
new Claim("Email", "testEmail"),
};
var authSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes("qwertyuiopasdfghjklzxcvbnm123456"));
var token = new JwtSecurityToken(
issuer: "https://localhost",
audience: "https://localhost",
expires: DateTime.Now.AddHours(3),
claims: authClaims,
signingCredentials: new Microsoft.IdentityModel.Tokens.SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
);
return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
expiration = token.ValidTo
});
}
return Unauthorized();
}
MVC上的/ account / login发布操作
var httpClient = _httpClientFactory.CreateClient("API");
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("username", username),
new KeyValuePair<string, string>("password", password)
});
var response = await httpClient.PostAsync("https://localhost:{port}/auth", formContent);
if (response.IsSuccessStatusCode)
{
var tokenResponse = await response.Content.ReadAsStringAsync();
var json = JsonDocument.Parse(tokenResponse);
var token = json.RootElement.GetProperty("token").GetRawText();
var expires = json.RootElement.GetProperty("expiration").GetRawText();
var jwt = new JwtSecurityToken(token);
//Access claims from jwt here, set the identity claims
//Set cookie authentication for MVC
var iden = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(iden);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
//Redirect to account page
}
从API正确返回了令牌,但是给出了“具有三个段,但不是正确的JWS格式”。在“ var jwt = new JwtSecurityToken(token);”处出现错误步骤。
我做错了吗?我应该使用带有登录表单Submit的javascript直接发布到API,是否将JWT添加到标题并将MVC切换到JwtBearer身份验证?
答案 0 :(得分:1)
我遇到了同样的问题,我设法使用以下代码读取令牌:
jwt = jwt.Replace("Bearer ", string.Empty);
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = tokenHandler.ReadJwtToken(jwt);
然后您可以使用jwtToken.Claims
集合查看声明。