1. 概要

Keycloak は、Spring Bootアプリケーションとうまく統合できるオープンソースのIDおよびアクセス管理(IAM)システムです。 このチュートリアルでは、Spring BootアプリケーションでKeycloakユーザーIDを取得する方法について説明します。

2. 問題文

Keycloakは、REST APIの保護、ユーザーフェデレーション、きめ細かい承認、ソーシャルログイン、2要素認証(2FA)などの機能を提供します。 さらに、OpenID Connect( OIDC )を使用したシングルサインオン( SSO )の実装にも使用できます。 Keycloakを使用してOIDCによって保護されたSpring Bootアプリケーションがあり、Spring BootアプリケーションでユーザーIDを取得したいとします。 この状況では、Spring Bootアプリケーションでアクセストークンまたはセキュリティコンテキストを取得する必要があります。

2.1. 承認サーバーとしてのKeycloakサーバー

簡単にするために、Spring Bootアプリケーションに埋め込まれたKeycloakを使用します。 GitHubで利用可能な認証サーバープロジェクトを使用していると仮定します。 まず、組み込みKeycloakサーバーのレルムbaeldungcustomerClientクライアントを定義します。 次に、レルムの詳細を customer-realm.json としてエクスポートし、レルムファイルをapplication-customer.ymlに設定します。

keycloak:
  server:
    contextPath: /auth
    adminUser:
      username: bael-admin
      password: pass
    realmImportFile: customer-realm.json

最後に、 – spring .profiles.active =customerオプションを使用してアプリケーションを実行できます。 これで、認証サーバーの準備が整いました。 サーバーを実行した後、 http:// localhost:8083 /auth/。にある認証サーバーのウェルカムページにアクセスできます。

2.2. リソースサーバー

承認サーバーを構成したので、リソースサーバーを設定しましょう。 そのために、GitHubで利用可能なリソースサーバープロジェクトを使用します。 まず、application-embedded.propertiesファイルをリソースとして追加しましょう。

keycloak.auth-server-url=http://localhost:8083/auth
keycloak.realm=baeldung
keycloak.resource=customerClient
keycloak.public-client=true
keycloak.principal-attribute=preferred_username

これで、リソースサーバーはOAuth2認証サーバーを使用して安全になり、リソースにアクセスするにはSSOサーバーにログインする必要があります。 – spring .profiles.active =embeddedオプションを使用してアプリケーションを実行できます。

3. KeycloakユーザーIDを取得する

KeycloakからユーザーIDを取得するには、アクセストークンまたはクライアントマッパーを使用するなど、いくつかの方法があります。

3.1. アクセストークンによる

Spring BootアプリケーションCustomUserAttrController クラスの上に構築し、 getUserInfo()メソッドを変更してユーザーIDを取得しましょう。

@GetMapping(path = "/users")
public String getUserInfo(Model model) {

    KeycloakAuthenticationToken authentication = 
      (KeycloakAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();

    Principal principal = (Principal) authentication.getPrincipal();

    String userIdByToken = "";

    if (principal instanceof KeycloakPrincipal) {
        KeycloakPrincipal<KeycloakSecurityContext> kPrincipal = (KeycloakPrincipal<KeycloakSecurityContext>) principal;
        IDToken token = kPrincipal.getKeycloakSecurityContext().getIdToken();
        userIdByToken = token.getSubject();
    }

    model.addAttribute("userIDByToken", userIdByToken);
    return "userInfo";
}

ご覧のとおり、最初にKeycloakAuthenticationTokenクラスからPrincipalを取得しました。 次に、 getSubject()メソッドを使用して、IDTokenからユーザーIDを抽出します。

3.2. クライアントマッパーによる

クライアントマッパーにユーザーIDを追加し、Spring Bootアプリケーションで取得できます。 まず、customerClientクライアントでクライアントマッパーを定義します。 次に、CustomUserAttrControllerクラスのユーザーIDを取得します。

@GetMapping(path = "/users")
public String getUserInfo(Model model) {

    KeycloakAuthenticationToken authentication = 
      (KeycloakAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();

    Principal principal = (Principal) authentication.getPrincipal();

    String userIdByMapper = "";

    if (principal instanceof KeycloakPrincipal) {
        KeycloakPrincipal<KeycloakSecurityContext> kPrincipal = (KeycloakPrincipal<KeycloakSecurityContext>) principal;
        IDToken token = kPrincipal.getKeycloakSecurityContext().getIdToken();
        userIdByMapper = token.getOtherClaims().get("user_id").toString();
    }

    model.addAttribute("userIDByMapper", userIdByMapper);
    return "userInfo";
}

マッパーの取得には、 IDTokengetOtherClaims()メソッドを使用します。 次に、モデル属性にユーザーIDを追加します。

3.3. Thymeleaf

userInfo.html テンプレートを変更して、ユーザーID情報を表示します。

<div id="container">
    <h1>
	User ID By Token: <span th:text="${userIDByToken}">--userID--</span>.
    </h1>
    <h1>
        User ID By Mapper: <span th:text="${userIDByMapper}">--userID--</span>.
    </h1>
</div>

3.4. テスト

アプリケーションを実行した後、 http:// localhost:8081 /usersに移動できます。 資格情報にbaeldung:baeldung と入力すると、次のようになります。

4. 結論

この記事では、Spring BootアプリケーションでKeycloakからユーザーIDを取得する方法について説明しました。 まず、安全なアプリケーションを呼び出すために必要な環境を設定します。 次に、IDTokenとクライアントマッパーを使用してSpring BootアプリケーションでKeycloakユーザーIDを取得する方法について説明しました。 いつものように、このチュートリアルの完全なソースコードは、GitHubから入手できます。 さらに、認証サーバーのソースコードはGitHubで入手できます。