В качестве дополнения к @ ответу Люка :
Причиной, по которой 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();