Microsoft Identity 2 SignInManager никогда не возвращает VerificationRequired - PullRequest
2 голосов
/ 20 марта 2019

Я пытаюсь добавить двухфакторную аутентификацию, используя пин-коды, отправленные по электронной почте.Шаг 2FA требуется пользователям только через 30 дней после последнего шага 2FA.

Технология проекта - ASP.NET MVC 5 с использованием EntityFramework 6 с пакетом NuGet версии 2.2.2 пакетов Microsoft.AspNet.Identity.(.Core, .EntityFramework, .Owin).

Я следовал советам в этом руководстве, но интегрировал их в уже существующее в моей компании решение: https://docs.microsoft.com/en-us/aspnet/identity/overview/features-api/two-factor-authentication-using-sms-and-email-with-aspnet-identity

Мои проблемы

SignInManager никогда не возвращает requireVerification при использовании PasswordSignIn Я предполагал, что следует ожидать этого состояния входа в систему, когда флаг «TwoFactorEnabled» имеет значение true в базе данных для каждогопользователь.Я не уверен, что мне следует использовать это, если я хочу, чтобы пользователи проходили проверку 2FA каждые 2 недели, так как у меня сложилось впечатление, что пользователям потребуется проходить это каждый раз.Или это, или я должен использовать временную метку, установленную для пользователя, чтобы определить, пора ли снова включить флаг «TwoFactorEnabled»?

Я не могу получить проверенный идентификатор пользователя при проверке кода Я думал, что после выполнения обычного PasswordSignIn сервер сможет получить идентификатор пользователя, например, при проверке правильности введенного пин-кода:

[HttpPost]
    [AllowAnonymous]
    public async Task<ActionResult> VerifyCode(string pin)
    {
        string userId = await SignInManager.GetVerifiedUserIdAsync().WithCurrentCulture();

        if (userId == null || String.IsNullOrEmpty(pin))
        {
            return View("Error");
        }

        var user = await UserManager.FindByIdAsync(userId);

        if (await UserManager.VerifyTwoFactorTokenAsync(user.Id, "EmailCode", pin))
        {
            await SignInManager.SignInAsync(user, false, false);
            return RedirectToAction("Index", "Dashboards");
        }
        else
        {
            ModelState.AddModelError("", "Invalid code");
        }

        return View();
    }

Это немного сбивает с толку, так какбольшинство руководств очень старые и используют AuthenticationManager, которого я никогда раньше не видел.

Как запретить пользователям просто переходить на другие страницы с экрана проверки, если они уже "успешно"вошли в систему с именем пользователя и паролем " Не смогут ли они обойти атрибут авторизации на этом этапе?

Что уже работает Я могу заставить UserManager отправить электронное письмо стокен (пин-код), и он будет успешно проверен, если я введу правильный идентификатор пользователя

Что у меня естьdone У меня есть стандартная / стандартная настройка Identity, поэтому мы в значительной степени используем стандартную конфигурацию, которая поставляется с новыми проектами MVC 5.

Startup.Auth:

// Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
        app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(10));

        // Enables the application to remember the second login verification factor such as phone or email.
        // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
        // This is similar to the RememberMe option when you log in.
        app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);

Настройка 2FA провайдера в ApplicationUserManager:

        manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser>
        {
            Subject = "Security Code",
            BodyFormat = "Your security code is {0}"
        });

        manager.EmailService = new EmailService();
        //manager.SmsService = new SmsService();
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider =
                new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }

        return manager;

Заранее большое спасибо за любую помощь.

1 Ответ

1 голос
/ 21 марта 2019

Думаю, я понял, в чем проблема.UserManager вернул 0 для GetValidTwoFactorProvidersAsync.Похоже, это происходит, когда электронное письмо не подтверждено для пользователя.Я попытался настроить параметры электронной почты в соответствии с подтверждением для пользователя, и теперь возвращается RequVerification.

Когда возвращается RequVerification, кажется, что пользователь не полностью вошел в систему, но я все еще могу получить идентификатор пользователя впоследующие вызовы проверки кода с использованием метода GetVerifiedUserId SignInManager.

Итак, теперь, когда пользователь входит в систему, прежде чем выполнить вход с паролем, я просто выполняю проверку, чтобы увидеть, когда пользователь в последний раз выполнил аутентификацию 2FA.Если прошло более 30 дней, я снова включаю флаг 2FA в базе данных.Затем, когда будет выполнен вход с паролем, я получу Requireverification, как и ожидалось, и смогу продолжить оставшуюся часть потока, как в случае любой стандартной проверки 2FA.

...