Idenity Server 4 Injecting additional claims in IAuthorizeInteractionResponseGenerator
Asked Answered
L

1

6

I am trying to port code from IdentityServer3 which used PreAuthenticate to provide a temporary impersonation of a user into a client application for our admins.

Following with the thread in here, I am overriding ProcessInteractionAsync in a custom IAuthorizeInteractionResponseGenerator. This works great and I have everything working, BUT, I can't add an extra claim to be sent back to the client application so that it knows this is an impersonated id_token. In replacing the Subject on ValidatedAuthorizeRequest in my override, I add an additional claim that specifies the user who started the impersonation but this claim does not follow through in the id_token or the access token. Here is my override:

public override async Task<InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
{
    string impersonatedUserName = request.GetPrefixedAcrValue("Impersonate:");
    if (!string.IsNullOrWhiteSpace(impersonatedUserName))
    {
        if (request.Client.AllowedScopes.Contains(Constants.ClaimTypes.Impersonation))
        {
            var currentUser;
            var impersonatedUser;

            //Omited code to verify eligibility to impersonate user

            if (impersonatedUser != null)
            {
                IEnumerable<string> requestedClaimTypes = request.Client.AllowedScopes;

                IdentityServerUser idSrvUser = new IdentityServerUser(impersonatedUser.Id.ToString())
                {
                    AuthenticationTime = Clock.UtcNow.UtcDateTime,
                    DisplayName = impersonatedUser.UserName,
                    IdentityProvider = !string.IsNullOrEmpty(impersonatedUser.PasswordHash) ? IdentityServerConstants.LocalIdentityProvider : "external"
                };

                ProfileDataRequestContext context = new ProfileDataRequestContext(
                    idSrvUser.CreatePrincipal(),
                    request.Client,
                    nameof(AuthorizeInteractionResponseGenerator),
                    requestedClaimTypes);

                await Profile.GetProfileDataAsync(context);

                //Need this claim to flow through to client
                context.IssuedClaims.Add(new Claim(Constants.ClaimTypes.Impersonation, currentUser.UserName));

                foreach (Claim claim in context.IssuedClaims)
                {
                    idSrvUser.AdditionalClaims.Add(claim);
                }

                ClaimsPrincipal newSubject = idSrvUser.CreatePrincipal();

                request.Subject = newSubject;

                Logger.LogInformation("Impersonation set, returning response");

                return new InteractionResponse();
            }
            else
            {
                Logger.LogWarning("Invalid attempt to impersonate user");
                return new InteractionResponse { Error = "Invalid attempt to impersonate user" };
            }
        }
        else
        {
            Logger.LogWarning("Client does not support impersonation!");
            return new InteractionResponse { Error = "Client does not support impersonation" };
        }
    }

    return await base.ProcessInteractionAsync(request, consent);
}

I added a scope for this special claim that the client requests, but it still is not being included. I feel like there is something obvious I am missing here, how do I add an extra claim to one of the tokens? Or is there a better way to signal the client who started the impersonation?

Latchet answered 27/10, 2017 at 21:48 Comment(0)
L
0

So I ended up taking a slightly different route than I did in Identity Server 3 to solve this requirement. Instead of appending the username in Identity Server, I store the username of the user who started the impersonation at the client in a temporary cookie. Then in the AuthorizationCodeReceived notification, I check for the cookie value and append the claim to the principal being created there.

Not quite as foolproof as appending the claim in Identity, but since all the major security checks still happen and the stuff I wanted to know who was doing it as an impersonated user will fail without the cookie, this will work. If anyone else comes across this and does figure out how to append the claim in identity server, respond and I will give you the answer

Latchet answered 30/10, 2017 at 15:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.