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());
}
});
}
しかし、私は 2 番目のタスク (HTTP 要求の送信) に行き詰まっています。trusted client token
もう一方のサービスは、指定されたKeycloak Client
とを使用して を要求するように設定されていますscope
。同等の POST リクエストauth/realms/{realm}/protocol/openid-connect/token
は、次のパラメーターを使用して実行されます。
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 が発生したのか、それともカスタム EventHandler の実行が完了するまで Keycloak が待機しているのかはわかりません。
(それを理解するために、アドオンコード内から通常のhttp POSTリクエストを使用してそのトークンを取得できるかどうか試してみますが、内部からそのようにKeycloakに接続できるかどうかはわかりません. それが機能する場合は、質問を更新します。)
どんな提案でも大歓迎です!
(こちらのKeycloak談話グループでもこれを尋ねましたが、そこでは未回答のままになるようです)