Keycloak KeyClope SPI:只能为此脱机令牌更改用户吗?

Keycloak KeyClope SPI:只能为此脱机令牌更改用户吗?,keycloak,Keycloak,默认情况下,同意和脱机令牌与客户端和当前登录的用户关联 我们希望为公司而不是员工发行离线代币 我们应用程序的客户是公司。离线令牌表示公司之间的关系。当前登录的用户只是具有建立此关系的相关权限的代理。因此,当合作伙伴客户端使用身份验证代码流请求脱机令牌时,我们希望将脱机令牌颁发给代表当前用户雇主的“用户”,即用户工作的公司,而不是登录的当前用户 动机:我们希望避免当用户不可避免地辞职时,当我们删除该用户时,离线令牌变得无效,并且我们可以在一次API调用中获得该公司的所有同意,因此我们不必查询每个员

默认情况下,同意和脱机令牌与客户端和当前登录的
用户关联

我们希望为公司而不是员工发行离线代币 我们应用程序的客户是公司。离线令牌表示公司之间的关系。当前登录的用户只是具有建立此关系的相关权限的代理。因此,当合作伙伴客户端使用身份验证代码流请求脱机令牌时,我们希望将脱机令牌颁发给代表当前用户雇主的“用户”,即用户工作的公司,而不是登录的当前用户

动机:我们希望避免当用户不可避免地辞职时,当我们删除该用户时,离线令牌变得无效,并且我们可以在一次API调用中获得该公司的所有同意,因此我们不必查询每个员工的同意以获得完整情况

但是,当员工登录时,我们如何获得为雇主发放的离线代币

我试过的 我试着问了一个不太详细的问题。到目前为止还没有答案

因此,现在我使用身份验证SPI在身份验证过程结束时创建一个
Authenticator
,在员工登录之后,我们即将完成身份验证。在
public void authenticate(AuthenticationFlowContext){}
中,我可以看到当前登录的员工用户的上下文

因此,为了简单起见,假设我想将用户更改为“acme”,如果客户ID为“PartnerCompany”

context.getAuthenticationSession()
中,我可以获得一个包含此注释(重新包装)的:

/**
*表示身份验证的状态。如果请求登录
*从同一浏览器的不同选项卡中,每个浏览器选项卡都有自己的选项卡
*身份验证的状态。
*因此,每个选项卡都有单独的AuthenticationSessionModel。全浏览器
*由{@link RootAuthenticationSessionModel}表示
*
*@作者
*/
AuthenticationSessionModel
有一个方法:

void setAuthenticatedUser(UserModel用户)
所以我认为我是金色的!我只能为此选项卡设置用户。我的计划就是在
authenticate()
中基本上做到这一点:

AuthenticationSessionModel authSession=context.getAuthenticationSession();
如果(authSession.getClient().getClientId().equals(“PartnerCompany”)){
UserModel user=context.getSession().users().getUserByUsername(“acme”,realm);
if(user==null)
抛出新的RuntimeException(“无用户acme”);
logger.warn(“将用户设置为”+user.getUsername());
authSession.setAuthenticatedUser(用户);
}
现在怎么办? 这并没有达到我的预期。如果SSO会话已经处于活动状态,我会看到一条日志消息,上面说
将用户设置为acme
,但令牌中的用户仍然是登录的用户,而不是acme。如果没有活动的SSO会话,则向“acme”发出令牌,SSO变为活动状态,SSO会话中的所有客户端都以用户“acme”身份登录:-(

我还尝试了
context.fork()
context.clearUser()
context.setUser(user)
的各种组合,或者用户没有在令牌中更改,或者用户在SSO会话和令牌中都更改了。但我只想更改令牌和注册同意中的用户,而不是SSO会话中的用户

当然,我们可以实现一个非标准的端点,它可以进行某种形式的令牌交换:给员工一个令牌,它会给雇主返回一个令牌,但这就不那么优雅了

那么,是否有某种方法可以仅为该客户端更改用户,以便为用户“acme”注册许可,并将脱机令牌注册为用户“acme”,但SSO会话仍保留为原始员工用户