I configure IdentityServer4
to use AspNet Identity (.net core 3.0) in order to allow users to authenticate using 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" />
I'm facing to the same issue and I found two solutions.
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;
});
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>();