Mostafa
Mostafa

Reputation: 3302

ClaimType.GivenName doesn't return my first name

I am developing .net core 2.2 application that authenticates from Azure AD. I would like to get the user's first name in the _LoginPartial.cshtml in RAZOR web app. I am able to get the user's surname and email but not the first name. Is there away to get this?

This is what i have in my login partial view:

Claim nameClaim = User.Claims.FirstOrDefault<Claim>(claim => string.Compare(claim.Type, "name", StringComparison.Ordinal) == 0);
    string userName = (nameClaim != null) && !string.IsNullOrEmpty(nameClaim.Value) ? nameClaim.Value : ((User != null) && (User.Identity != null) ? User.Identity.Name : string.Empty);

Also i tried this:

@User.FindFirst(System.Security.Claims.ClaimTypes.GivenName).Value

The given name returns email same as name and email properties!!

What would be the ideal way to get the first name by extending the identity model in asp.net?

Upvotes: 0

Views: 3625

Answers (1)

Edward
Edward

Reputation: 30016

For Identity, there is no FirstName in the built-in IdentityUser, you need to implement your own user like:

public class ApplicationUser:IdentityUser
{
    public string FirstName { get; set; }
}

Then, implement UserClaimsPrincipalFactory<ApplicationUser>

public class CustomClaimsIdentityFactory : UserClaimsPrincipalFactory<ApplicationUser>
{
    public CustomClaimsIdentityFactory(UserManager<ApplicationUser> userManager
        , IOptions<IdentityOptions> optionsAccessor) 
        : base(userManager, optionsAccessor)
    {
    }

    public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
    {
        var principal = await base.CreateAsync(user);
        //custom claims
        ((ClaimsIdentity)principal.Identity).AddClaims(new[] {
          new Claim("FirstName", user.FirstName)
          });
        return principal;
    }
}

Then, you could check the FirstName by @User.Claims.FirstOrDefault(c => c.Type == "FirstName")?.Value like

@using Microsoft.AspNetCore.Identity
@using TestIdentity.Data
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> UserManager

<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
    <li class="nav-item">
        <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Claims.FirstOrDefault(c => c.Type == "FirstName")?.Value!</a>
    </li>
    <li class="nav-item">
        <form  class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })">
            <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>
        </form>
    </li>
}
else
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
}
</ul>

Upvotes: 2

Related Questions