我正在尝试从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);
}
我为客户要求的此特殊声明添加了一个范围,但它仍未被包含在内。我觉得这里有一些显而易见的东西,我如何在其中一个代币中添加额外的声明?或者是否有更好的方式来通知开始模仿的客户?
答案 0 :(得分:0)
所以我最终采用了与Identity Server 3中稍微不同的路线来解决这个问题。我没有在Identity Server中附加用户名,而是将在客户端开始模拟的用户的用户名存储在临时cookie中。然后在AuthorizationCodeReceived通知中,我检查cookie值并将声明附加到在那里创建的主体。
并不像在Identity中附加声明一样万无一失,但由于所有主要的安全检查仍然发生,并且我想知道谁作为模仿用户做的事情将在没有cookie的情况下失败,这将起作用。如果有其他人遇到此问题并确定如何在身份服务器中附加声明,请回复,我会给你答案