Оказывается, моя проблема возникла из-за вызова UserController.UserLogin()
до попытки проверки двухфакторной аутентификации.
Теперь, когда я звоню, после двухфакторной проверки все работает, как ожидалось, и даже последовательно: o)
Код
Вот пример того, что изменилось.
Вот что не сработало:
private void ValidateUser(UserInfo objUser, bool ignoreExpiring)
{
UserValidStatus validStatus = UserValidStatus.VALID;
string strMessage = Null.NullString;
DateTime expiryDate = Null.NullDate;
bool okToShowPanel = true;
validStatus = UserController.ValidateUser(objUser, PortalId, ignoreExpiring);
if (PasswordConfig.PasswordExpiry > 0)
{
expiryDate = objUser.Membership.LastPasswordChangeDate.AddDays(PasswordConfig.PasswordExpiry);
}
UserId = objUser.UserID;
//Check if the User has valid Password/Profile
switch (validStatus)
{
case UserValidStatus.VALID:
//check if the user is an admin/host and validate their IP
if (Host.EnableIPChecking)
{
bool isAdminUser = objUser.IsSuperUser || PortalSettings.UserInfo.IsInRole(PortalSettings.AdministratorRoleName); ;
if (isAdminUser)
{
if (IPFilterController.Instance.IsIPBanned(Request.UserHostAddress))
{
new PortalSecurity().SignOut();
AddModuleMessage("IPAddressBanned", ModuleMessage.ModuleMessageType.RedError, true);
okToShowPanel = false;
break;
}
}
}
//Set the Page Culture(Language) based on the Users Preferred Locale
if ((objUser.Profile != null) && (objUser.Profile.PreferredLocale != null))
{
Localization.SetLanguage(objUser.Profile.PreferredLocale);
}
else
{
Localization.SetLanguage(PortalSettings.DefaultLanguage);
}
//Set the Authentication Type used
AuthenticationController.SetAuthenticationType(AuthenticationType);
var userRequestIPAddress = new UserRequestIPAddressController();
//Complete Login
UserController.UserLogin(PortalId, objUser, PortalSettings.PortalName, userRequestIPAddress.GetUserRequestIPAddress(new HttpRequestWrapper(Request)), RememberMe);
var twoFactorAuthStatus = GetTwoFactorAuthStatus(objUser);
switch (twoFactorAuthStatus)
{
case TwoFactorAuthStatus.Error:
return;
case TwoFactorAuthStatus.NotEnabled:
RedirectUser(objUser);
break;
case TwoFactorAuthStatus.SetupNeeded:
PageNo = googleAuthSetupPageNo;
break;
case TwoFactorAuthStatus.VerificationNeeded:
PageNo = verifyGoogleAuthPageNo;
break;
}
break;
case UserValidStatus.PASSWORDEXPIRED:
strMessage = string.Format(Localization.GetString("PasswordExpired", LocalResourceFile), expiryDate.ToLongDateString());
AddLocalizedModuleMessage(strMessage, ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = passwordPageNo;
pnlProceed.Visible = false;
break;
case UserValidStatus.PASSWORDEXPIRING:
strMessage = string.Format(Localization.GetString("PasswordExpiring", LocalResourceFile), expiryDate.ToLongDateString());
AddLocalizedModuleMessage(strMessage, ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = passwordPageNo;
pnlProceed.Visible = true;
break;
case UserValidStatus.UPDATEPASSWORD:
AddModuleMessage("PasswordUpdate", ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = passwordPageNo;
pnlProceed.Visible = false;
break;
case UserValidStatus.UPDATEPROFILE:
//Save UserID in ViewState so that can update profile later.
UserId = objUser.UserID;
//When the user need update its profile to complete login, we need clear the login status because if the login is from
//3rd party login provider, it may call UserController.UserLogin because they doesn't check this situation.
new PortalSecurity().SignOut();
//Admin has forced profile update
AddModuleMessage("ProfileUpdate", ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = profilePageNo;
break;
}
if (okToShowPanel) ShowPanel();
}
Вот что сработало:
private void ValidateUser(UserInfo objUser, bool ignoreExpiring)
{
UserValidStatus validStatus = UserValidStatus.VALID;
string strMessage = Null.NullString;
DateTime expiryDate = Null.NullDate;
bool okToShowPanel = true;
validStatus = UserController.ValidateUser(objUser, PortalId, ignoreExpiring);
if (PasswordConfig.PasswordExpiry > 0)
{
expiryDate = objUser.Membership.LastPasswordChangeDate.AddDays(PasswordConfig.PasswordExpiry);
}
UserId = objUser.UserID;
//Check if the User has valid Password/Profile
switch (validStatus)
{
case UserValidStatus.VALID:
//check if the user is an admin/host and validate their IP
if (Host.EnableIPChecking)
{
bool isAdminUser = objUser.IsSuperUser || PortalSettings.UserInfo.IsInRole(PortalSettings.AdministratorRoleName); ;
if (isAdminUser)
{
if (IPFilterController.Instance.IsIPBanned(Request.UserHostAddress))
{
new PortalSecurity().SignOut();
AddModuleMessage("IPAddressBanned", ModuleMessage.ModuleMessageType.RedError, true);
okToShowPanel = false;
break;
}
}
}
var twoFactorAuthStatus = GetTwoFactorAuthStatus(objUser);
switch (twoFactorAuthStatus)
{
case TwoFactorAuthStatus.Error:
return;
case TwoFactorAuthStatus.NotEnabled:
LoginUser(objUser);
break;
case TwoFactorAuthStatus.SetupNeeded:
PageNo = googleAuthSetupPageNo;
break;
case TwoFactorAuthStatus.VerificationNeeded:
PageNo = verifyGoogleAuthPageNo;
break;
}
break;
case UserValidStatus.PASSWORDEXPIRED:
strMessage = string.Format(Localization.GetString("PasswordExpired", LocalResourceFile), expiryDate.ToLongDateString());
AddLocalizedModuleMessage(strMessage, ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = passwordPageNo;
pnlProceed.Visible = false;
break;
case UserValidStatus.PASSWORDEXPIRING:
strMessage = string.Format(Localization.GetString("PasswordExpiring", LocalResourceFile), expiryDate.ToLongDateString());
AddLocalizedModuleMessage(strMessage, ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = passwordPageNo;
pnlProceed.Visible = true;
break;
case UserValidStatus.UPDATEPASSWORD:
AddModuleMessage("PasswordUpdate", ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = passwordPageNo;
pnlProceed.Visible = false;
break;
case UserValidStatus.UPDATEPROFILE:
//Save UserID in ViewState so that can update profile later.
UserId = objUser.UserID;
//When the user need update its profile to complete login, we need clear the login status because if the login is from
//3rd party login provider, it may call UserController.UserLogin because they doesn't check this situation.
new PortalSecurity().SignOut();
//Admin has forced profile update
AddModuleMessage("ProfileUpdate", ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = profilePageNo;
break;
}
if (okToShowPanel) ShowPanel();
}
Я изменил RedirectUser()
из первого примера на LoginUser()
, который также выполняет перенаправление. LoginUser()
также вызывается после успешной двухфакторной аутентификации и / или настройки.
Это более безопасный способ справиться с этим в целом. Обратная связь по отладке, которую я получал, была просто super , что вводило в заблуждение.