Для схемы «Identity.TwoFactorUserId» не зарегистрирован обработчик аутентификации выхода. - PullRequest
0 голосов
/ 24 июня 2019

Веб-приложение ASP.NET Core 2.2 с использованием кода, перенесенного из полнофункционального приложения MVC.

My AccountController содержит этот простой код для Logout маршрута.

await this.SignInManager.SignOutAsync();
return this.RedirectToAction(nameof(Landing.HomeController.Index), "Home");

Но это дает.

Нет обработчика аутентификации выхода из системы для схемы 'Identity.TwoFactorUserId'.

Довольно запутанно, учитывая, что я никогда не упоминал 2FA в своем коде, и вход в Google работает.

serviceCollection
    .AddIdentityCore<MyUser>(identityOptions =>
    {
        identityOptions.SignIn.RequireConfirmedEmail = false;
    })
    .AddUserStore<MyUserStore>()
    .AddSignInManager<SignInManager<MyUser>>();

serviceCollection.AddAuthentication(IdentityConstants.ApplicationScheme)
    .AddCookie(IdentityConstants.ApplicationScheme, options =>
    {
        options.SlidingExpiration = true;
    })
    .AddGoogle(googleOptions =>
    {
        this.Configuration.Bind("OAuth2:Providers:Google", googleOptions);

        googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
    })
    .AddExternalCookie();

Ответы [ 2 ]

1 голос
/ 25 июня 2019

В качестве дополнения к @ ответу Люка :

Причиной, по которой SignInManager::SignOutAsync() выбрасывает этот метод, также будет выделено TwoFactorUserIdScheme за кадром:

public virtual async Task SignOutAsync()
{
    await Context.SignOutAsync(IdentityConstants.ApplicationScheme);
    await Context.SignOutAsync(IdentityConstants.ExternalScheme);
    await Context.SignOutAsync(<b>IdentityConstants.TwoFactorUserIdScheme</b>);
}

(См. исходный код )

Обычно эти схемы аутентификации по дереву регистрируются автоматически по AddIdentity<TUser, TRole>():

public static IdentityBuilder AddIdentity<TUser, TRole>(
    this IServiceCollection services,
    Action<IdentityOptions> setupAction)
{
    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
        options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
        options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
    })
    ...
    .AddCookie(<b>IdentityConstants.TwoFactorUserIdScheme</b>, o =>
    {
        o.Cookie.Name = IdentityConstants.TwoFactorUserIdScheme;
        o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
    });
    ... // other services
}

(См. исходный код )

Однако вы добавили услуги Identity с помощью AddIdentityCore<>() вместо AddIdentity<>().

Поскольку AddIdentityCore<>() не регистрирует схему TwoFactorUserIdScheme (см. исходный код ) автоматически, для TwoFactorUserIdScheme нет связанных CookieAuthenticationHandler.В результате выдает.


Как решить

Чтобы работать с SignInManager.SignOutAsync(), согласно приведенному выше описанию, нам необходимо обеспечить <scheme>-<handler> карта зарегистрирована на TwoFactorUserIdScheme.

Итак, я изменил ваш код, как показано ниже, теперь он отлично работает для меня:

serviceCollection.AddAuthentication(IdentityConstants.ApplicationScheme)
    .AddCookie(IdentityConstants.ApplicationScheme, options =>
    {
        options.SlidingExpiration = true;
    })
    <b>.AddCookie(IdentityConstants.TwoFactorUserIdScheme, o =>
    {
        o.Cookie.Name = IdentityConstants.TwoFactorUserIdScheme;
        o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
    })</b>
    .AddGoogle(googleOptions =>
    {
        this.Configuration.Bind("OAuth2:Providers:Google", googleOptions);
        googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
    })
    .AddExternalCookie();
0 голосов
/ 25 июня 2019

Не используйте метод SignOutAsync для SignInManager<T>, который вы ввели в контроллер. Вместо этого используйте метод для HttpContext, который принимает аргумент scheme. Я не знаю почему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...