Elias Nawfal
Elias Nawfal

Reputation: 231

Passing Data to IProfileService in IdentityServer4

I am using IdtentityServer4 where I have a scenario when a support personnel want to login on behalf of a user for support.

When this happens I want to know throughout my ASP.NET Core app that this support guy is acting on behalf of the user with a message on the screen that says:
"Mr Support on Behalf of Ms Username"

I am currently implementing IProfileUser for normal login. I am looking for a way to add an extra "attribute" to include the username of the support person in token without accessing the database.

I tried to pass items

await _signInManager.SignInAsync(applicationUser, new AuthenticationProperties
{
    Items = {new KeyValuePair<string, string>("SupportName", "Mr Support")}
}).ConfigureAwait(false);

But I don't know how to get them from the ProfileDataRequestContext passed to GetProfileDataAsync in IProfileService implementation.

This is my IProfileService implementation:

public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
    ClaimsPrincipal claimsPrincipal = context.Subject;
    if (claimsPrincipal == null)
    {
        throw new ArgumentNullException(nameof(context.Subject));
    }
    string id = claimsPrincipal.GetSubjectId();
    ApplicationUser user = await _userManager.FindByIdAsync(id).ConfigureAwait(false);
    if (user == null)
    {
        throw new ArgumentException("Invalid user identifier");
    }
    context.IssuedClaims.Add(new Claim(JwtClaimTypes.Email, user.Email));
    IList<string> roles = await _userManager.GetRolesAsync(user).ConfigureAwait(false);
    foreach (var role in roles)
    {
        context.IssuedClaims.Add(new Claim(JwtClaimTypes.Role, role));
    }

    context.IssuedClaims.Add(new Claim(JwtClaimTypes.Name, user.Name));
}

Upvotes: 2

Views: 1451

Answers (1)

Richard
Richard

Reputation: 1584

You could pass this data via a claim.

Modify your sign-in code to include the "SupportName" claim:

// Sign in the user and include the SupportName claim
await HttpContext.SignInAsync(userId, username, new Claim("SupportName", "Mr Support"));

and access this claim in GetProfileDataAsync:

    public async Task GetProfileDataAsync(ProfileDataRequestContext context) {
        // Find the "SupportName" claim added during sign-in
        var supportNameClaim = context.Subject.FindFirst("SupportName");
        if (supportNameClaim != null) {
            Console.WriteLine($"Signed in on behalf of {supportNameClaim.Value}");
        }

        // Issue all the claims (if required)
        context.IssuedClaims.AddRange(context.Subject.Claims);
    }

Upvotes: 2

Related Questions