Asp Core 2.1 Jwt + личность. Хранилище userManager не реализует IUserRoleStore - PullRequest
0 голосов
/ 06 сентября 2018

Я пытаюсь работать с аутентификацией Jwt и Identity в ASP Net Core 2.1

В моем Startup.cs у меня есть:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.RequireHttpsMetadata = false;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = AuthOptions.ISSUER,
            ValidateAudience = true,
            ValidAudience = AuthOptions.AUDIENCE,
            ValidateLifetime = true,
            IssuerSigningKey = AuthOptions.GetSymmetricSecurityKey(),
            ValidateIssuerSigningKey = true,
        };
    });

var builder = services.AddIdentityCore<User>(options =>
{
    // Password settings
    ...
    // Lockout settings
    ...
    // User settings
    options.User.RequireUniqueEmail = true;
}).AddEntityFrameworkStores<ApplicationDbContext>();

builder = new IdentityBuilder (builder.UserType, typeof (IdentityRole), builder.Services);

Затем в SecurityService.cs я пытаюсь получить роли с помощью этого оператора

var roles = await _userManager.GetRolesAsync(user);

И его выбрасывает следующее исключение:

NotSupportedException: Store не реализует IUserRoleStore
Microsoft.AspNetCore.Identity.UserManager.GetUserRoleStore ()

Я нашел это из-за AddIdentityCore: Если я использую AddIdentity<User, IdentityRole> вместо этого он работает, но тогда [Authorize] не работает

Кто-нибудь сталкивался с подобной ситуацией или почему это может произойти?

1 Ответ

0 голосов
/ 06 сентября 2018

Когда вы используете AddIdentity<TUser, TRole>, этот вызов настраивает схему аутентификации по умолчанию, например: ( source ):

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
    options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})

В вашем Startup.ConfigureServices есть следующее: также устанавливает схему аутентификации по умолчанию:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

Из-за порядка, в котором это определено (AddIdentity равно после AddAuthentication), значение по умолчанию меняется с Jwt на Identity, поэтому при использовании [Authorize] процесс проверки подлинности теперь ожидая использовать Identity, а не Jwt.

Для решения этой проблемы простейшим вариантом является переключение порядка AddIdentity и AddAuthentication, чтобы вызов JwtBearer был последним и, следовательно, "выигрывал". Вы также должны быть более точными и установить DefaultAuthenticateScheme и DefaultChallengeScheme:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(...);

Другим вариантом является явное указание в атрибуте [Authorize], вызывая , какую схему аутентификации вы хотите использовать, как любую из следующих двух строк:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Authorize(AuthenticationSchemes = IdentityConstants.ApplicationScheme)]

Кажется, что первый вариант будет наиболее подходящим для вашего варианта использования, но хорошо знать, что этот второй вариант существует, если он вам нужен, когда вы идете дальше с Identity (есть и другие - например, с использованием политик).

...