Andreas
Andreas

Reputation: 1776

How to set ClaimsPrincipal.Identity.Name from Claim with custom type in ASP.NET Core WebApi

I use JWT Bearer to secure my WebApi endpoints. All works fine so far but I am wondering why the "Name" property of the ClaimsIdentity of the ClaimsPrincipal is null. I can remember somewhere to find the information, that this property is set from the content of a Claim of type "name" (correct???). I have a Claim of type "username" in my JWT that contains the username and I try to find a way to map that into the HttpContext.User.Identy.Name property.

Is there any configuration for that?

EDIT: The whole project is only for educational purposes, that is the reason for the quite simple code...

This is how I set the Claim:

private string GenerateJwtToken(User user)
{
    // generate token that is valid for 7 days
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes(_appSettings.JwtSecret);

    var claims = new List<Claim>
    {
        new("id", user.Id.ToString()),
        new("username", user.Username)
    };

    if (user.Username == "pbrause")
        claims.Add(new("weatherForecast", "true"));

    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(claims),
        Expires = DateTime.UtcNow.AddDays(7),
        Issuer = "me",
        Audience = "you",
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),
        IssuedAt = DateTime.UtcNow
    };

    var token = tokenHandler.CreateToken(tokenDescriptor);

    return tokenHandler.WriteToken(token);
}

Upvotes: 7

Views: 10643

Answers (3)

david-1160
david-1160

Reputation: 112

Like described in this blogpost, you have to specify the custom name property in the ClaimsIdentity constructor. If you want to have

new Claim("username", user.Username) 

for the Identity Name property populated, you have to use the constructor

Subject = new ClaimsIdentity(claims, ClaimTypes.Authentication, "username",  ClaimTypes.Role),

Notice the "username" string.

Upvotes: 4

Maks Shapovalov
Maks Shapovalov

Reputation: 184

In method where you call AddJwtBearer or something else you could customize it with TokenValidationParameters.NameClaimType

Example:

services.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, o =>
             {
                 ...
                 o.TokenValidationParameters.NameClaimType = "username";
                 ...
              })

Upvotes: 4

Xinran Shen
Xinran Shen

Reputation: 9963

I use ClaimTypes.Name as key and user.username as value to set the claim, Then i can get user name in HttpContext.User.Identy.Name.

 List<Claim> claims = new List<Claim>
    {
         new Claim(ClaimTypes.Name, user.UserName),
                        
         //..........
     };

Demo:

enter image description here

Upvotes: 6

Related Questions