web-dev-qa-db-fra.com

User.Identity.Name est vide dans le contrôleur d'API Asp.NET Core 2.0

Je suis nouveau sur le noyau ASP.NET lui-même. Cependant, je crée des WebAPI dans ASP.NET Core 2.0. J'ai configuré l'authentification basée sur le jeton de porteur JWT. Ci-dessous est mon contrôleur qui retourne un jeton.

    [AllowAnonymous]
[Route("api/[controller]")]
public class TokenController : Controller
{
    private readonly UserManager<UserEntity> userManager;
    private readonly SignInManager<UserEntity> signInManager;

    public TokenController(UserManager<UserEntity> userManager, SignInManager<UserEntity> signInManager)
    {
        this.userManager = userManager;
        this.signInManager = signInManager;
    }

    // GET: api/values
    [HttpGet]
    public async Task<IActionResult> Get(string username, string password, string grant_type)
    {
        {
            var user = await userManager.FindByEmailAsync(username);

            if (user != null)
            {
                var result =await signInManager.CheckPasswordSignInAsync(user, password, false);
                if (result.Succeeded)
                {

                    var claims = new[]
                    {
                        new Claim( JwtRegisteredClaimNames.Sub, username),
                        new Claim( JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                        new Claim( JwtRegisteredClaimNames.GivenName, "SomeUserID")
                    };

                    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("secretesecretesecretesecretesecretesecrete"));
                    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                    var token = new JwtSecurityToken( issuer: "test",
                                                     audience: "test",
                                                     claims: claims,
                                                      expires: DateTime.Now.AddDays(15),
                                                      signingCredentials: creds);

                    return Ok(new { access_token = new JwtSecurityTokenHandler().WriteToken(token), expires_on=DateTime.Now.AddDays(15) });

                }
            }
        }

        return BadRequest("Could not create token");
    }


}

Mais lors de l'appel à l'API ValuesController qui est décorée d'attributs [Authorize]. Je reçois ser.Identity.Name est vide. Je ne reçois aucune information sur l'utilisateur. Je ne suis pas sûr, mon contrôleur de jeton est correctement écrit. Tant qu'il protège mon ValuesController, je suppose que c'est correct. Cependant, je manque peut-être quelque chose. Veuillez aider.

Remarque: je développe à l'aide de Visual Studio 2017 avec l'ajout de la communauté Mac

10
Nps

Oui, vous devez spécifier la revendication du nom unique qui est traduit dans user.identity.name:

new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName)
22
Shawn Wildermuth

J'ai également eu ce problème avec ASP.Net Core 2, et je suis vraiment surpris que personne n'ait découvert l'autre cause de ce problème.

Lorsque ma webapp est déployée sur IIS, "User.Identity.Name "renvoie toujours null. Le site IIS a l'accès anonyme désactivé et l'authentification Windows est activée.

MAIS.

Je ne savais pas que mon ASP.Net Core 2 avait un "launchSettings.json ", discrètement caché sous le dossier Properties, et là-dedans, il y a aussi quelques iisSettings, et ici" windowsAuthentication "était étrangement défini comme faux par défaut.

enter image description here

Changer "windowsAuthentication" en true et "anonymousAuthentication" en false a résolu le problème pour moi.

Après cela, "User.Identity.Name "contenait enfin le nom d'utilisateur correct.

Mais qu'est-ce que c'est que ce réglage? Pourquoi cela serait-il prioritaire sur les paramètres réels que nous avons configurés dans IIS Manager?!

9
Mike Gledhill

A eu ce problème aussi (Core 3.1) en utilisant le "DefaultIdentity" (comptes d'utilisateurs individuels). User.Identity.Name est null, User.Identity.IsAuthenticated = true. En utilisant httpContextAccessor, vous pouvez obtenir l'ID utilisateur avec cet identifiant, vous pouvez trouver l'utilisateur et le nom d'utilisateur. Dans votre contrôleur, ajoutez

using System.Security.Claims;
...
private readonly IHttpContextAccessor _httpContextAccessor;
public MyController(MyContext context, IHttpContextAccessor httpContextAccessor)
{
  _context = context;
  _httpContextAccessor = httpContextAccessor;
}

// Any method username needed
[HttpGet("{id}")]
public async Task<ActionResult<MyInfo>> GetMyInfo(int id)
{
  var userId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
  var user = _context.AspNetUsers.Find(userId);
  var userName = user.UserName;
  ...
}

Dans Startup.cs, ajoutez la ligne suivante:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
0
Gerard