Bildsoe
Bildsoe

Reputation: 1350

Does ProfileService.GetProfileDataAsync replace default scopes/claims in Identity Server 4

In a Identity Server 4 setup, I've added the scopes "email" and "profile" to a client. This causes the claims within these scopes to be added to the users token, which is sent from Identity Server to my application. This works as intended.

I needed to add a custom claim to the token. I did that using

public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
            
    var user = await _userManager.GetUserAsync(context.Subject);

    var claims = new List<Claim>();
           
    claims.Add(new Claim("Tenant", user.Tenant));

    context.IssuedClaims.AddRange(claims);
}

This also works, but I'm unsure whether it works as intended or not. When using this method all the claims added by default no longer gets added. I have to manually add claims from the scopes "email" and "profile". I do this in a manner like the following:

if (context.RequestedResources.ParsedScopes.Any(x => x.ParsedName == "email"))
{
    claims.Add(new Claim(ClaimTypes.Email, user.Email));
}

if (context.RequestedResources.ParsedScopes.Any(x => x.ParsedName == "profile"))
{
    claims.Add(new Claim(ClaimTypes.Name, user.UserName));
    claims.Add(new Claim("preferred_username", user.UserName));
}

Should this be necessary? is this working as intended or did I mess something up?

Upvotes: 1

Views: 318

Answers (1)

d_f
d_f

Reputation: 4869

It's not clear from the explanation what implementation of IProfileService you use as a base.
If it is the Default one, you can extend it like:

public override async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
    var user = await _userManager.GetUserAsync(context.Subject);

    context.AddRequestedClaims(new[]{new Claim("Tenant", user.Tenant)});

    await base.GetProfileDataAsync(context); //here the default implementation adds 
                                             //claims from Subject (e.g. the cookie)
                                             //and logs the result
}

If you use ASP.NET Identity, you might want to play with this one.

Upvotes: 0

Related Questions