Idenity Server 4在IAuthorizeInteractionResponseGenerator中注入其他声明

时间:2017-10-27 21:48:49

标签: openid identityserver4 oidc

我正在尝试从IdentityServer3移植代码,该代码使用PreAuthenticate为我们的管理员提供用户临时模拟客户端应用程序。

跟随here中的线程,我在自定义IAuthorizeInteractionResponseGenerator中重写ProcessInteractionAsync。这很好用,我有一切工作,但是,我不能添加额外的声明被发送回客户端应用程序,以便它知道这是一个模仿的id_token。在我的覆盖中替换ValidatedAuthorizeRequest上的主题时,我添加了一个额外的声明,指定启动模拟的用户,但此声明未在id_token或访问令牌中贯彻执行。这是我的覆盖:

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);
}

我为客户要求的此特殊声明添加了一个范围,但它仍未被包含在内。我觉得这里有一些显而易见的东西,我如何在其中一个代币中添加额外的声明?或者是否有更好的方式来通知开始模仿的客户?

1 个答案:

答案 0 :(得分:0)

所以我最终采用了与Identity Server 3中稍微不同的路线来解决这个问题。我没有在Identity Server中附加用户名,而是将在客户端开始模拟的用户的用户名存储在临时cookie中。然后在AuthorizationCodeReceived通知中,我检查cookie值并将声明附加到在那里创建的主体。

并不像在Identity中附加声明一样万无一失,但由于所有主要的安全检查仍然发生,并且我想知道谁作为模仿用户做的事情将在没有cookie的情况下失败,这将起作用。如果有其他人遇到此问题并确定如何在身份服务器中附加声明,请回复,我会给你答案