GoogleAuthenticator (2FA) не проходит проверку в мобильных браузерах, но работает на настольных компьютерах в C# и ASP.NC#

Место общения программистов C#
Ответить
Anonymous
 GoogleAuthenticator (2FA) не проходит проверку в мобильных браузерах, но работает на настольных компьютерах в C# и ASP.N

Сообщение Anonymous »

Я реализую двухфакторную аутентификацию в проекте C# и ASP.NET MVC, используя пакет GoogleAuthenticator NuGet (v3.2.0).
Проблема: аутентификация отлично работает во всех настольных браузерах. Однако при использовании мобильного браузера (Chrome или Safari на iOS/Android) метод ValidateTwoFactorPIN постоянно возвращает false, даже если введенный код соответствует именно тому, что отображается в приложении Google Authenticator.
Что я пробовал:
  • Подтвердил, что строка пароля правильно доходит до контроллера на мобильном устройстве (ровно 6 цифр)
  • Подтверждено, что UserUniqueKey (секрет) единообразен во всех сеансах настольного компьютера и мобильного устройства.
  • Проверено, что браузеры настольных компьютеров работают в 100 % случаев, а мобильные устройства не работают в 100 % случаев.
Поскольку OTP основан на времени, я подозреваю, что проблема в синхронизации. Однако мобильный телефон и сервер синхронизируются по времени в Интернете.
Почему эта проверка может завершиться неудачно именно в мобильных браузерах? Существует ли известная проблема с тем, как аутентификатор Google обрабатывает временные окна или как мобильные браузеры могут отправлять запросы?
Моя настройка: представление (ввод OTP): я использую шесть отдельных полей ввода для лучшего взаимодействия с пользователем. Я использую JavaScript, чтобы объединить их в одну строку перед отправкой через AJAX.

Enter OTP
Enter OTP from the Google Authenticator App...











Verify



Сценарий на стороне клиента: я очищаю ввод, чтобы гарантировать отправку только цифр.
$("#btnVerify").on("click", function () {
const passcodeDigits = [];

for (let i = 1; i 0)
passcodeDigits.push(value.charAt(0));
}

const passcode = passcodeDigits.join("");
const UserUniqueKey = $("#HfUserUniqueKey").val();

$.ajax({
type: "POST",
url: "/Login/Verify2FA",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ passcode: passcode, UserUniqueKey: UserUniqueKey }),
success: function (d) {
if (d === "Y") window.location.href = "/Home/Index";
else alert("Enter correct OTP...");
}
});
});

onKeyUpEvent и onFocusEvent
function onKeyUpEvent(index, event) {
const $element = getCodeBoxElement(index);
let value = $element.val();
value = value.replace(/\D/g, ''); // Remove all non-digits

if (value.length > 1) {
value = value.charAt(0);
}
$element.val(value);

if (event.which === 8 || event.keyCode === 8) {
if (value.length === 0 && index !== 1) {
getCodeBoxElement(index - 1).focus();
}
}
else if (value.length === 1) {
if (index !== 6) {
getCodeBoxElement(index + 1).focus();
} else {
$element.blur();
}
}
}

function onFocusEvent(index) {
for (let i = 1; i < index; i++) {
const $current = getCodeBoxElement(i);
if (!$current.val()) {
$current.focus();
break;
}
}
}

Контроллер на стороне сервера:
[HttpPost]
public JsonResult Verify2FA(string passcode, string UserUniqueKey)
{
if (string.IsNullOrWhiteSpace(passcode) || UserUniqueKey == null)
return Json("N");

TwoFactorAuthenticator tfa = new TwoFactorAuthenticator();

// UserUniqueKey is the secret saved in the DB
bool isValid = tfa.ValidateTwoFactorPIN(UserUniqueKey, passcode.Trim());

if (isValid)
{
FormsAuthentication.SetAuthCookie(Session["UserID_Temp"].ToString(), false);
return Json("Y");
}

return Json("N");
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... s-on-deskt
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»