我正在创建一个 Web 应用程序,我已经通过工作登录屏幕实现了所有内容,其中令牌通过 DTO 传递并保存到浏览器的 LocalStorage 中,但是我遇到了问题。
我尝试按照一些文档和视频添加两因素身份验证,但在过去的三周里我面临着一个烦人的困难。
当我尝试登录时,它会按预期向给定的电子邮件地址发送 OTP 代码。 -(电子邮件已验证并且双因素已启用。)
但是,当我想使用验证 API 方法来验证用户并传递用户名和代码时,它在后端工作(使用我的端点 - Swagger 进行测试),但无法通过我的 Blazor 客户端应用程序工作。
[HttpPost("verification")]
public async Task<IActionResult> LoginWithOTP([FromBody] UserVerification userVerification/*string code, string username*/)
{
var user = await signInManager.UserManager.FindByNameAsync(userVerification.Username);
var signIn = await signInManager.TwoFactorSignInAsync("Email", userVerification.Code, false, false);
if (signIn.Succeeded)
{
var roles = await signInManager.UserManager.GetRolesAsync(user!);
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.UserName)
};
foreach (var role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JWT:Secret"]!));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var expiry = DateTime.Now.AddDays(Convert.ToInt32(configuration["JWT:ExpiryInDays"]));
var token = new JwtSecurityToken(
configuration["JWT:ValidIssuer"],
configuration["JWT:ValidAudience"],
claims,
expires: expiry,
signingCredentials: creds
);
return Ok(new UserLoginResult { Successful = true, Token = new JwtSecurityTokenHandler().WriteToken(token) });
}
return BadRequest("Invalid code.");
}
在浏览器中,我发现当您尝试登录并向电子邮件发送代码时,会创建一个名为 Identity.TwoFactorUserId 的 cookie,该 cookie 使用
'signInManager.UserManager.GenerateTwoFactorTokenAsync(user, "Email")'
方法生成,因此在 Swagger 中使用登录端点后,我可以成功使用验证端点 - 因为它们位于同一页面上。
但是当我尝试使用 blazor 客户端应用程序登录时,不会创建此 cookie,因此我假设
signInManager.TwoFactorSignInAsync("Email", userVerification.Code, false, false);
由于验证端点 API 中的原因而失败。
这就是我尝试使用 Swagger 中的 Enpoint 登录时的样子:
这就是我尝试使用 Blazor 客户端应用程序登录时缺少的内容。
我试图找到在哪里可以获取此 Identity.TwoFactorUserId 令牌以手动传递到 Blazor 客户端应用程序,但我所能找到的只是通常这是自动处理的。
我很迷茫,我将不胜感激任何建议或帮助。
提前谢谢您!
下午好。我理解您的沮丧,因为我面临着完全相同的情况。我们有一个实现双因素安全性的 APIRest。但由于某种原因,从 Blazor 使用时它会失败。无论是在 Swagger 中还是使用 Postman 都可以完美运行。而且我仍在寻找解决方案,所以我会非常关注这篇文章,看看是否有朋友可以给我们一个解决方案或不同的方法......非常感谢!