David
David

Reputation: 3157

Identity Server - how to I include with token additional claims (from external identity provider)

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

Answers (1)

nahidf
nahidf

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

Related Questions