クライアントポリシーを利用したKeycloakの設定方法と、FAPIリファレンス実装の紹介
第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)も利用可能です。
<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が有効になります。
<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を参照してください。
<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)をクリックします。
クリックすると、作成するキーペアの設定項目が表示されるので、Algorithm でPS256(またはP-256)を選択し、Saveをクリックします。
キーペアが作成されると、Activeタブの一覧にAlgorithmがPS256、ES256となっている鍵が表示されます。
クライアントの設定
ここからクライアントを作成して必要な設定をしていきます。クライアントの概要は下記の通りです。
# | client id | Access Type | 役割 |
---|---|---|---|
1 | fapi-client | Confidential | クライアントアプリケーション |
2 | fapi-resource-server | bearer-only | リソースサーバー |
クライアントポリシーの適用
作成したクライアントにクライアントポリシーを適用するため、クライアントアプリケーションにfapi1advロールを追加します。
Valid Redirect URIsの設定
Valid Redirect URIsにはクライアントアプリケーションのパスを指定します。今回のサンプルアプリケーションではhttps://localhost:8082/callbackを指定してください。
署名、暗号化アルゴリズムの設定
IDトークンやリクエストオブジェクトの署名アルゴリズムや暗号アルゴリズムの詳細は、Fine Grain OpenID Connect Configuration で行います。
必要な設定は下記の通りです。
# | 設定項目 | 設定値 | 備考 |
---|---|---|---|
1 | ID Token Encryption Key Management Algorithm | - | IDトークンの暗号化を行う場合はRSA-OAEPまたはRSA-OAEP-256を選択する |
2 | ID Token Encryption Content Encryption Algorithm | - | IDトークンの暗号化を行う場合は選択が必要 |
3 | Request Object Signature Algorithm | PS256 | ES256でも動作可能 |
4 | Request Object Required | request 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の設定は完了となります。
リファレンス実装を利用した動作確認
ここからはリファレンス実装のアプリケーションを利用して、簡単な動作確認をしていきます。
クライアント、リソースサーバの起動
下記のコマンドを実行し、クライアントアプリケーション、リソースサーバをそれぞれ起動します。
$ cd client $ mvn spring-boot:run
$ cd server $ mvn spring-boot:run
エラー等が発生していなければ、クライアントは8082番ポート、リソースサーバは8081番ポートで起動します。
アクセストークンの取得
まずはクライアントにアクセスするため、ブラウザでhttps://localhost:8082/を開きます。
この画面から、アクセストークンの取得やリフレッシュ/失効、APIリクエストの実行が行えます。Get Tokenボタンを押下すると認可リクエストが作成され、Keycloakの認可エンドポイントにリダイレクトされます。
設定済みのファイルをインポートしている場合はuser/passで認証ができます。認証が成功すると、アクセストークン、リフレッシュトークン、IDトークンがそれぞれ取得できます。
API リクエストの実行
アクセストークンの取得後にCall APIボタンを押下すると、アクセストークン付きのAPIリクエストが実行できます。リソースサーバには、下記のエンドポイントを用意してあります。
# | パス | 返却値 |
---|---|---|
1 | / | 固定値({"status" : "ok" }) |
2 | /me | 認証されたユーザの情報(username、sub claim) |
3 | /echo/{value} | {value}で指定された値 |
4 | /introspection | Token Introspectionの結果 |
5 | /headers | リクエストヘッダーの内容 |
まとめ
今回は Keycloak のクライアントポリシーを利用した設定方法と、FAPI 1.0に対応したリファレンス実装を用いた簡単な動作を紹介しました。
次回はリファレンス実装の実装方法と使い方をより詳細に説明します。