クライアントポリシーを利用したKeycloakの設定方法と、FAPIリファレンス実装の紹介

2021年12月21日(火)
茂木 昂士(もぎ たかし)
連載3回目となる今回は、FAPIのリファレンス実装を利用して、FAPI 1.0の動作を確認していきます。

第3回では、前回紹介したクライアントポリシーを利用してKeycloakを設定し、GitHubに公開したFAPIのリファレンス実装を利用してFAPI 1.0の動作を確認していきます。

FAPIのリファレンス実装に関して

Keycloakをはじめ、FAPI 1.0に対応した認可サーバの実装はいくつかあり、実装に関する情報なども公開されています。しかし現状では、クライアント/リソースサーバの実装に関する情報や、対応したライブラリ/フレームワークはほとんどありません。FAPI 1.0の普及を進めていくために、今回の連載にあわせてFAPIリファレンス実装を公開しました。このリファレンス実装ではSpring BootおよびNimbus Jose+JWTを利用して、FAPI 1.0に対応したクライアント、リソースサーバを作成しました。

今回は、このリファレンス実装を動作させるためのKeycloakの設定、およびクライアント/リソースサーバの簡単な動作説明を行っていきます。なお詳細な実装内容の紹介や、動作の説明は第4回で行います。

リファレンス実装の構成

リファレンス実装のファイル/ディレクトリ構成は下記のようになっています。

hitachi-fapi-java
├── README.md
├── client               // クライアントアプリケーション
│     ├── src
│     └── pom.xml
├── server               // リソースサーバ
│     ├── src
│     └── pom.xml
├── keycloak-export.json // 認可サーバ用 import 用ファイル
├── keycloak.p12         // 認可サーバ用 HTTPS 用 keystore
├── truststore.p12       // 認可サーバ用 Trust Store
└── pom.xml

鍵/証明書の設定や、設定済みの Keycloak から Export したファイルも公開しているので、そちらも利用してください。

Keycloak の設定

ここからは、リファレンス実装のアプリケーションを動作させるため、Keycloakの設定をしていきます。Keycloakのバージョンは、執筆時点で最新の15.0.2を利用します。

HTTPS/mTLS の設定

まずは、Keycloakが動作するアプリケーションサーバ(Wildfly)に対して、HTTPS/mTLSを設定していきます。mTLSに関しては、Server AdministrationドキュメントのEnable X.509 Client Certificate User Authenticationを参考に設定します。ドキュメントでは、ユーザ認証の際にX.509証明書を利用するための設定ですが、クライアント認証の際に利用する場合も同じ設定となります。

まずは、新規のsecurity-realmを作成し、HTTPSに利用する証明書の情報と、mTLSの検証に利用するtruststoreを設定します。なお、動作の確認等で単純に動作させたい場合は、リポジトリにある設定済みのKeystoreファイル(keycloak.p12、truststore.p12)も利用可能です。

リスト1:security-realmの作成とtruststoreの設定

<security-realm name="ssl-realm">
    <server-identities>
        <ssl>
            <keystore path="keycloak.p12"
                relative-to="jboss.server.config.dir"
                keystore-password="password"
                alias="keycloak"
                key-password="password"/>
        </ssl>
    </server-identities>
    <authentication>
        <truststore path="truststore.p12"
                relative-to="jboss.server.config.dir"
                keystore-password="password"/>
    </authentication>
</security-realm>

security-realmの設定後、https-listenerに対して設定をします。https-listenerのverify-clientをREQUESTEDにすることで、mTLSが有効になります。

リスト2:https-listenerの設定

<https-listener name="https"
    socket-binding="https"
    security-realm="ssl-realm"
    enable-http2="true"
    verify-client="REQUESTED"/>

最後にKeycloakが外部のサーバと通信する際に利用するTruststore SPIの設定をします。今回は自己証明書を利用しているため必要となります。設定の詳細に関しては、KeycloakのServer InstallationドキュメントOutgoing HTTPS Request Truststoreを参照してください。

リスト3:Truststore SPIの設定

<spi name="truststore">
    <provider name="file" enabled="true">
        <properties>
            <property name="file" value="standalone/configuration/truststore.p12" />
            <property name="password" value="password" />
            <property name="hostname-verification-policy" value="WILDCARD" />
            <property name="disabled" value="false" />
        </properties>
    </provider>
</spi>

Keycloak起動前の設定は以上となります。

以降の設定はfapiというRealmを作成し、そのRealmに対して設定を行っていきます。

クライアントポリシーの作成

第2回の記事を参考に、FAPI Advanced Security Profile 1.0のクライアントポリシーを作成します。クライアントポリシーを作成すると、fapi1advというロールがついたクライアントにポリシーが適用されるようになります。

Key Providerの作成

FAPI 1.0では、IDトークンの署名アルゴリズムにPS256またはES256が要求されています。Keycloakの初期設定では、これらの署名アルゴリズムに対応するキーペアが設定されていません。これらの署名アルゴリズムに対応するため、必要となるキーペアを作成していきます。

まず、Realm Settings→Keys→Providersタブを選択し、右上の「Add keystore...」からrsa-generated(ES256を利用する場合はecdsa-generated)をクリックします。

Key Providerの追加

Key Providerの追加

クリックすると、作成するキーペアの設定項目が表示されるので、Algorithm でPS256(またはP-256)を選択し、Saveをクリックします。

rsa-generated Key Providerの追加

rsa-generated Key Providerの追加

キーペアが作成されると、Activeタブの一覧にAlgorithmがPS256、ES256となっている鍵が表示されます。

PS256、ES256鍵の追加結果

PS256、ES256鍵の追加結果

クライアントの設定

ここからクライアントを作成して必要な設定をしていきます。クライアントの概要は下記の通りです。

#client idAccess Type役割
1fapi-clientConfidentialクライアントアプリケーション
2fapi-resource-serverbearer-onlyリソースサーバー

クライアントポリシーの適用

作成したクライアントにクライアントポリシーを適用するため、クライアントアプリケーションにfapi1advロールを追加します。

ロールの追加

ロールの追加

Valid Redirect URIsの設定

Valid Redirect URIsにはクライアントアプリケーションのパスを指定します。今回のサンプルアプリケーションではhttps://localhost:8082/callbackを指定してください。

署名、暗号化アルゴリズムの設定

IDトークンやリクエストオブジェクトの署名アルゴリズムや暗号アルゴリズムの詳細は、Fine Grain OpenID Connect Configuration で行います。

署名、暗号化アルゴリズムの設定

署名、暗号化アルゴリズムの設定

必要な設定は下記の通りです。

#設定項目設定値備考
1ID Token Encryption Key
Management Algorithm
IDトークンの暗号化を行う場合はRSA-OAEPまたはRSA-OAEP-256を選択する
2ID Token Encryption Content Encryption AlgorithmIDトークンの暗号化を行う場合は選択が必要
3Request Object Signature AlgorithmPS256ES256でも動作可能
4Request Object Requiredrequest only 

IDトークンの暗号化に関してはFAPI 1.0では必須ではありませんが、今回のリファレンス実装では暗号化にも対応しています。IDトークンの暗号化を試したい場合は、ID Token Encryption Key Management Algorithmに設定した値を、クライアントのapplication.yamlファイルに指定してください。

クライアント認証方式の設定

FAPI 1.0では、クライアント認証方式としてtls_client_auth(クライアント証明書による認証)とprivate_key_jwt(JWTを利用した認証)の2つの方式が規定されています。リファレンス実装ではデフォルトでtls_client_authを使うように設定されているため、ここではtls_client_authの設定方法を説明します。

クライアント認証方式の設定

クライアント認証方式の設定

クライアントのCredentialsタブで、クライアントの認証方式を設定します。tls_client_authを利用する場合は、Client AuthenticatorにX509 Certificateを指定します。Subject DNには、クライアント証明書で設定したDN(Distinguished Name)を設定します。リファレンス実装では設定済みの証明書があるので、その証明書にあわせてクライアントにはCN=fapi-client、リソースサーバにはCN=fapi-resource-serverと設定します。

クライアント側の署名、暗号鍵の設定

最後にリクエストオブジェクトの署名や、IDトークンの暗号化に利用する鍵情報を設定します。この設定はクライアントアプリケーションに対してのみ行います。

鍵情報の設定

鍵情報の設定

リファレンス実装ではJWKを公開するURLを用意しているので、Use JWKS URLをONに、JWKS URLにhttps://localhost:8082/jwk_setを設定します。

以上でKeycloakの設定は完了となります。

リファレンス実装を利用した動作確認

ここからはリファレンス実装のアプリケーションを利用して、簡単な動作確認をしていきます。

クライアント、リソースサーバの起動

下記のコマンドを実行し、クライアントアプリケーション、リソースサーバをそれぞれ起動します。

リスト4:クライアントアプリケーションの起動

$ cd client
$ mvn spring-boot:run

リスト5:リソースサーバの起動

$ cd server
$ mvn spring-boot:run

エラー等が発生していなければ、クライアントは8082番ポート、リソースサーバは8081番ポートで起動します。

アクセストークンの取得

まずはクライアントにアクセスするため、ブラウザでhttps://localhost:8082/を開きます。

クライアントアプリケーションのトップ画面

クライアントアプリケーションのトップ画面

この画面から、アクセストークンの取得やリフレッシュ/失効、APIリクエストの実行が行えます。Get Tokenボタンを押下すると認可リクエストが作成され、Keycloakの認可エンドポイントにリダイレクトされます。

Keycloak でのログイン

Keycloak でのログイン

設定済みのファイルをインポートしている場合はuser/passで認証ができます。認証が成功すると、アクセストークン、リフレッシュトークン、IDトークンがそれぞれ取得できます。

アクセストークンの取得結果

アクセストークンの取得結果

API リクエストの実行

アクセストークンの取得後にCall APIボタンを押下すると、アクセストークン付きのAPIリクエストが実行できます。リソースサーバには、下記のエンドポイントを用意してあります。

#パス返却値
1/固定値({"status" : "ok" })
2/me認証されたユーザの情報(username、sub claim)
3/echo/{value}{value}で指定された値
4/introspectionToken Introspectionの結果
5/headersリクエストヘッダーの内容

まとめ

今回は Keycloak のクライアントポリシーを利用した設定方法と、FAPI 1.0に対応したリファレンス実装を用いた簡単な動作を紹介しました。

次回はリファレンス実装の実装方法と使い方をより詳細に説明します。

著者
茂木 昂士(もぎ たかし)
株式会社日立製作所 OSSソリューションセンタ
株式会社日立製作所 OSSソリューションセンタ所属。これまではソフトウェアエンジニアとしてストレージやサーバの管理ソフトウェア開発に従事してきた。現在は、主にアイデンティティー管理OSSやAPI管理OSSの検証、導入支援を行っている。

連載バックナンバー

セキュリティ技術解説
第4回

FAPI 1.0に準拠したクライアントアプリケーションと リソースサーバの作り方

2022/1/18
連載4回目となる今回は、FAPI 1.0に準拠したクライアントアプリケーションと リソースサーバの作り方を解説します。
セキュリティ技術解説
第3回

クライアントポリシーを利用したKeycloakの設定方法と、FAPIリファレンス実装の紹介

2021/12/21
連載3回目となる今回は、FAPIのリファレンス実装を利用して、FAPI 1.0の動作を確認していきます。
セキュリティ技術解説
第2回

Keycloakのクライアントポリシー(Client Policies)

2021/11/9
連載の2回目となる今回は、さまざまなセキュリティプロファイルをサポートするための仕組み、クライアントポリシーをご紹介します。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています