Reputation: 3157
I am having a hard time finding solid information about how to send additional claims to my client application from identity server.
At the current moment, I am using the following to get a local claim (that I captured within ProcessLoginCallbackForOidc) and added to the claims being returned during authentication.
Is this the best approach?
public class ProfileService : IProfileService
{
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
//var sub = context.Subject.GetSubjectId();
var claims = context.Subject.Claims.ToList();
if (claims.Count > 0)
{
var emailClaim = claims.FirstOrDefault(x => x.Type == "email");
if (emailClaim == null)
{
var emailAddressClaim = context.Subject.Claims.FirstOrDefault(x => x.Type == "emails");
if (emailAddressClaim != null)
{
claims.Add(new Claim("email", emailAddressClaim.Value));
}
}
}
// Set returned claims (System.Security.Claims.Claim) by setting context.IssuedClaims
context.IssuedClaims = claims;
return Task.CompletedTask;
}
public Task IsActiveAsync(IsActiveContext context)
{
context.IsActive = true;
return Task.CompletedTask;
}
}
Upvotes: 1
Views: 390
Reputation: 2394
Yes this is proper solution. ProfileService
is an extensibility point to add extra claims for a user.
Its called when creating token for the user.
Read more here
Edit: Here is sample code for profile service:
public class ProfileService : IProfileService
{
private readonly IUserClaimsPrincipalFactory<ApplicationUser> _claimsFactory;
private readonly UserManager<ApplicationUser> _userManager;
public ProfileService(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();
if (claims.Count > 0)
{
var emailClaim = claims.FirstOrDefault(x => x.Type == "email");
if (emailClaim == null)
{
var emailAddressClaim = context.Subject.Claims.FirstOrDefault(x => x.Type == "emails");
if (emailAddressClaim != null)
{
claims.Add(new Claim("email", emailAddressClaim.Value));
}
}
}
context.IssuedClaims = claims;
return Task.CompletedTask;
}
public async Task IsActiveAsync(IsActiveContext context)
{
var sub = context.Subject.GetSubjectId();
var user = await _userManager.FindByIdAsync(sub);
context.IsActive = user != null;
}
}
Upvotes: 1