Аутентификация JWT - UserManager.GetUserAsync возвращает ноль - PullRequest
0 голосов
/ 01 июля 2018

В AuthController при аутентификации я создаю несколько утверждений - UserID является одним из них.

...
Subject = new ClaimsIdentity(new[]
{
  new Claim(ClaimTypes.Name, user.UserName),
  new Claim("UserID", user.Id.ToString()),
})

Когда приложение Angular отправляет запрос, я могу получить UserID на другом контроллере

Claim claimUserId = User.Claims.SingleOrDefault(c => c.Type == "UserID");

Экземпляр ControllerBase.User содержит объект .Identity, который в свою очередь содержит коллекцию Claims.

  • Identity.IsAuthenticated равно True.

  • Identity.Name содержит admin строку (имя соответствующего пользователя).

Если я попытаюсь вызвать пользователя следующим образом:

var user = await UserManager.GetUserAsync(HttpContext.User)

user является null.

Возможно, я забыл добавить дополнительную заявку?

Или, может быть, как только я использую JWT - я должен переопределить функциональность UserManager по умолчанию, чтобы он выбирал пользователя по claim, который содержит UserID?

Или, может быть, есть лучший подход?


Дополнительная информация:

Identity зарегистрирован следующим образом

services.AddIdentity<ApplicationUser, ApplicationRole>()
    .AddEntityFrameworkStores<AppDbContext>()
    .AddDefaultTokenProviders();

ApplicationUser.Id поле имеет bigint (или в C # long) тип

Кроме того, я создаю пользователей в EF Seed Data с помощью UserManager, который разрешается с помощью ServiceProvider

_userManager = scope.ServiceProvider.GetService<UserManager<ApplicationUser>>();
    ...
        adminUser.PasswordHash = new PasswordHasher<ApplicationUser>().HashPassword(adminUser, "123qwe");
        _userManager.CreateAsync(adminUser);

1 Ответ

0 голосов
/ 01 июля 2018

UserManager.GetUserAsync внутренне использует UserManager.GetUserId для получения идентификатора пользователя, который затем используется для запроса объекта из хранилища пользователей (т. Е. Вашей базы данных).

GetUserId в основном выглядит так:

public string GetUserId(ClaimsPrincipal principal)
{
    return principal.FindFirstValue(Options.ClaimsIdentity.UserIdClaimType);
}

Таким образом, возвращается значение претензии Options.ClaimsIdentity.UserIdClaimType. Options - это IdentityOptions объект , с которым вы настраиваете Identity. По умолчанию значение UserIdClaimType равно ClaimTypes.NameIdentifier, т.е. "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier".

Поэтому, когда вы пытаетесь использовать UserManager.GetUserAsync(HttpContext.User), где у этого принципала пользователя есть утверждение UserID, менеджер пользователя просто ищет другое утверждение.

Это можно исправить, переключившись на ClaimTypes.NameIdentifier:

new ClaimsIdentity(new[]
{
    new Claim(ClaimTypes.Name, user.UserName),
    new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
})

Или вы правильно настроили Identity, поэтому он будет использовать UserID тип заявки:

// in Startup.ConfigureServices
services.AddIdentity(options => {
    options.ClaimIdentity.UserIdClaimType = "UserID";
});
...