我已经构建了一个带有 Angular 前端的 ASP.NET Core 网站。它通过 ASP.NET Core Identity 实现外部登录(Facebook、Twitter、Google、Microsoft)。上周,我实施了 2 因素身份验证以与 Authenticator 应用程序一起使用。
我已将 Web 应用程序发布到 Plesk 环境。使用电子邮件/密码登录时,验证器应用程序中的 2FA 代码工作正常。但是,当使用外部登录提供程序登录时,来自身份验证器应用程序的 2FA 代码似乎不起作用。
然而,当我在 IIS Express 上进行测试时,一切都按预期工作,我可以使用 Facebook 登录,从身份验证器应用程序输入 OTP 并登录。
该项目的代码托管在Github上。本质上是这样的:
// C#
// The user navigates to the url hosting the `Challenge` for the external login specified
var redirectUrl = Url.RouteUrl("web-v3-account-external-connect-callback", new { medium, provider });
var properties = signin_manager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
// After the user successfully signed in into the OAuth provider's login page
var info = await signin_manager.GetExternalLoginInfoAsync();
var user = await user_manager.FindByLoginAsync(info.LoginProvider, info.ProviderKey);
// ...
var signinResult = await signin_manager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, true, user.Bypass2faForExternalLogin);
if (signinResult.Succeeded) {
// ...
} else if (signinResult.RequiresTwoFactor) {
return View(new ExternalLoginResultVM {
Status = LoginStatus.RequiresTwoFactor
});
}
// Angular
// The above MVC response is messaged to the angular app, to which the angular app detects
// that it needs to show the page to ask for the 2-factor verification code
socialLoginDone(result: LoginResult) {
switch (result.status) {
case LoginStatus.requiresTwoFactor: {
this.router.navigate(['/account', 'two-factor'], {
queryParams: { return: this.returnUrl }
});
break;
}
}
}
// After the user entered the verification code, an ajax is being sent
verifyCode() {
this.httpClient.post<string[]>(`${this.baseUrl}/web/${this.apiVersion}/Account/two-factor-login`, {
code: this.setupCode,
remember: false
}).subscribe((backupCodes) => {
this.accountService.currentUser().then((user) => {
this.loginComplete.next(user);
this.router.navigateByUrl(this.returnUrl);
});
});
return false;
}
// C#
// performing the following code, which is also used for PasswordSignin
// https://github.com/MintPlayer/MintPlayer/blob/master/MP.Data/Repositories/AccountRepository.cs#L453
var user = await signin_manager.GetTwoFactorAuthenticationUserAsync();
var result = await signin_manager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, true, remember);
// This doesn't succeed for external login, on live environment.
if (result.Succeeded)
{
return userMapper.Entity2Dto(user, true);
}
else
{
throw new LoginException();
}
为什么这不起作用?我该如何解决这个问题?