作为我们努力符合 GDPR 的一部分,我正在尝试使用一些自定义功能扩展我们的 Keycloak 服务器,以便在删除用户时触发:
- 向 Slack 频道发送确认消息
- 向我们构建的另一个服务发送 HTTP 请求,以删除用户可能在那里创建的任何资产
第一个很容易。它被实现为 SPI 事件侦听器,遵循以下示例:
@Override
public void postInit(KeycloakSessionFactory keycloakSessionFactory) {
keycloakSessionFactory.register(
(event) -> {
// the user is available via event.getUser()
if (event instanceof UserModel.UserRemovedEvent){
userRemovedMessageHandler.handleUserRemoveEvent(session, (UserRemovedEvent) event);
LOG.debug("User removed event happened for user: " + ((UserRemovedEvent) event).getUser().getId());
}
});
}
但我坚持第二个任务(发送 HTTP 请求)。另一个服务被设置为需要一个trusted client token
,使用一个指定的Keycloak Client
和scope
。auth/realms/{realm}/protocol/openid-connect/token
使用以下参数完成等效的 POST 请求:
grant_type: password
username: {user that is about to be deleted}
password: {user password}
client_id: {the specific client}
client_secret: {that client's secret}
scope: usersets
我无法从 SPI 代码中找到如何做到这一点。我可以检索常规访问令牌(如其他 SO 帖子中所述):
private String getAccessToken(KeycloakSession session, UserModel deleteUser) {
KeycloakContext keycloakContext = session.getContext();
AccessToken token = new AccessToken();
token.subject(deleteUser.getId());
token.issuer(Urls.realmIssuer(keycloakContext.getUri().getBaseUri(), keycloakContext.getRealm().getName()));
token.issuedNow();
token.expiration((int) (token.getIat() + 60L)); //Lifetime of 60 seconds
KeyWrapper key = session.keys().getActiveKey(keycloakContext.getRealm(), KeyUse.SIG, "RS256");
return new JWSBuilder().kid(key.getKid()).type("JWT").jsonContent(token).sign(
new AsymmetricSignatureSignerContext(key));
}
但这不是我需要的令牌。为了检索所需的受信任客户端令牌,我需要上述 POST 请求的内部 Keycloak / SPI 等效项,但我不知道如何执行此操作或在哪里查看。
此外,我不确定是否甚至可以为正在被删除的用户检索受信任的客户端令牌。换句话说,我不知道 UserRemovedEvent 是否在用户被实际删除之前、期间或之后触发,或者 Keycloak 是否等待任何自定义 EventHandler 完成运行。
(为了弄清楚这一点,我将尝试是否可以使用附加代码中的常规 http POST 请求来检索该令牌,但我不知道是否可以从内部连接到 Keycloak .如果可行,我会更新问题。)
我将不胜感激任何建议!
(我在这里的 Keycloak 讨论组中也问过这个问题,但看起来它在那里仍然没有答案)