web-dev-qa-db-fra.com

Authentification JWT - UserManager.GetUserAsync renvoie null

Dans AuthController lors de l'authentification, j'en crée quelques Revendications - UserID en fait partie.

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

Lorsque Angular fait une demande, je peux récupérer UserID dans un autre contrôleur

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

L'instance ControllerBase.User Contient l'objet .Identity Qui à son tour contient la collection Claims.

  • Identity.IsAuthenticated Est égal à True.

  • Identity.Name Contient admin chaîne (nom de l'utilisateur concerné).

Si j'essaye de récupérer l'utilisateur comme ceci:

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

user est null.

Peut-être, j'ai oublié d'ajouter une réclamation supplémentaire?

Ou peut-être, une fois que j'utilise JWT - devrais-je remplacer la fonctionnalité UserManager par défaut afin qu'elle récupère l'utilisateur par claim qui contient UserID?

Ou peut-être y a-t-il une meilleure approche?


Information additionnelle:

Identity est enregistré comme suit

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

Le champ ApplicationUser.Id Est de type bigint (ou en C # de long)

De plus, je crée des utilisateurs dans EF Seed Data Avec UserManager qui est résolu en utilisant ServiceProvider

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

UserManager.GetUserAsync utilise en interne UserManager.GetUserId pour récupérer l'ID utilisateur de l'utilisateur qui est ensuite utilisé pour interroger l'objet dans le magasin d'utilisateurs (c.-à-d. votre base de données).

GetUserId ressemble à ceci:

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

Cela renvoie donc la valeur de réclamation de Options.ClaimsIdentity.UserIdClaimType. Options est le IdentityOptions objet avec lequel vous configurez Identity. Par défaut, la valeur de UserIdClaimType est ClaimTypes.NameIdentifier, C'est-à-dire "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier".

Ainsi, lorsque vous essayez d'utiliser UserManager.GetUserAsync(HttpContext.User), où cet utilisateur principal a une revendication UserID, le gestionnaire d'utilisateurs recherche simplement une revendication différente.

Vous pouvez résoudre ce problème en basculant vers le ClaimTypes.NameIdentifier:

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

Ou vous configurez correctement l'identité afin qu'elle utilise votre type de revendication UserID:

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