Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User.Identity.Name is null after local login

I configure IdentityServer4 to use AspNet Identity (.net core 3.0) in order to allow users to authenticate (login/password).

My third application is an WebApi in .net core 3.0.

After logging, authentication and authorization succeeded but I can't retrieve UserId through User.Identity.Name which is null/empty.

However, I can see the claims information which contain a sub claim containing the userId.

Here is the packages I use for my IdentityServer4 web app

PackageReference Include="IdentityServer4" Version="3.0.1" />
like image 668
Ghassen Avatar asked Dec 03 '19 10:12

Ghassen


1 Answers

I'm facing to the same issue and I found two solutions.

  • [Solution 1] - WebApi - Updating NameClaimType of IdentityServerAuthentication configuration

In your startup file of your WebApi, update the NameClaimType property

services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
        .AddIdentityServerAuthentication(options =>
         {
               options.CacheDuration = xxxxx;
               options.Authority = xxxxx;
               options.ApiName = xxxx;
               options.ApiSecret = xxxxx;
               options.RequireHttpsMetadata = xxxxxx;
               options.NameClaimType = JwtClaimTypes.Subject;
         });
  • [Solution 2] - IdentityServer4 App - Creating new profil to customize your claims

Create a new profil for IdentityServer4 server in order to customize claims inside the token.

public class AspNetIdentityProfileService : IProfileService
{
    private readonly IUserClaimsPrincipalFactory<ApplicationUser> _claimsFactory;
    private readonly UserManager<ApplicationUser> _userManager;

    public AspNetIdentityProfileService(UserManager<ApplicationUser> userManager, IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory)
    {
        _userManager = userManager;
        _claimsFactory = claimsFactory;
    }

    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var sub = context.Subject.GetSubjectId();
        var user = await _userManager.FindByIdAsync(sub);
        var principal = await _claimsFactory.CreateAsync(user);

        var claims = principal.Claims.ToList();

        claims = claims.Where(claim => context.RequestedClaimTypes.Contains(claim.Type)).ToList();

        claims.Add(new Claim("name", user.UserName));
        context.IssuedClaims = claims;
    }

    public async Task IsActiveAsync(IsActiveContext context)
    {
        var sub = context.Subject.GetSubjectId();
        var user = await _userManager.FindByIdAsync(sub);

        context.IsActive = user != null;
    }
}

In your startup file

services.AddTransient<IProfileService, AspNetIdentityProfileService>();
like image 132
Nicolas Law-Dune Avatar answered Oct 13 '22 09:10

Nicolas Law-Dune



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!