【发布时间】:2017-12-11 14:08:11
【问题描述】:
我有一个控制器可以登录我的用户。假设它是现有用户并且密码正确,我检查他们是否启用了 2fa。
AccountControler 登录方式
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, _configurationSettings.LockoutOnFailure);
if (result.Succeeded)
{
var user = await _userManager.FindByEmailAsync(model.Email);
await _signInManager.SignInAsync(user, _configurationSettings.IsPersistent);
_logger.LogInformation("User logged in.");
return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToAction(nameof(Lockout));
}
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
// If we got this far, something failed, redisplay form
return View(model);
}
假设用户确实启用了 2fa,然后我将他们重定向到 LoginWith2fa 方法。
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> LoginWith2fa(bool rememberMe, string returnUrl = null)
{
// Ensure the user has gone through the username & password screen first
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
if (user == null)
{
throw new ApplicationException($"Unable to load two-factor authentication user.");
}
var model = new LoginWith2faViewModel { RememberMe = rememberMe };
ViewData["ReturnUrl"] = returnUrl;
return View(model);
}
这是我的问题所在 var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); 总是返回 null。我放了几个断点,看起来它在 ApplicationSignInManager 和 AccountController 中重新调用了我的构造函数。在那里给我一个新的会话。
SignInManager 在 startup.cs 中注册为 scoped
services.AddIdentity<ApplicationUser, IdentityRole<long>>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddSignInManager<ApplicationSignInManager>()
.AddDefaultTokenProviders();
如何调用 RedirectToAction 并保留同一个会话?
我一直在关注这个项目Identity Server 4 Demo
【问题讨论】:
-
范围请求lifetime 仅适用于当前请求。通过使用
RedirectToAction,您将 302 发送回浏览器,然后浏览器向您的新操作发出 new 请求,从而创建新范围。 -
UseTwoFactorSignInCookie(...);出现在您的解决方案中吗? -
@Mackan 我认为这对于 ASP.NET Core 来说不是必需的。
-
@serpent5 啊,核心。我太落后了。 回到身份 2
-
纯粹为了诊断,看看在
LoginWith2fa中运行await HttpContext.AuthenticateAsync(IdentityConstants.TwoFactorUserIdScheme)返回的值 - 那是null?这是第一个电话,本质上是GetTwoFactorAuthenticationUserAsync中的第一个电话。
标签: c# asp.net-core .net-core identityserver4 two-factor-authentication