fbpx

Keycloak + Passkey でPasskey周りの挙動について確認! #keycloak  #passkey

この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。

1. 概要


shiba チームの中村です。前回の記事 では Keycloak でクライアントポリシーを設定し、 Financial-grade API Security Profile 1.0 - Part 2: Advanced](https://openid.net/specs/openid-financial-api-part-2-1_0.html) へ対応したクライアントの振る舞いを検証していました。

今回の記事では、最近流行りの Passkey についてKeycloakの対応状況及び、Passkeyの挙動を簡単に確認していきたいと思います。

2. What is Passkey?

まず Passkeyとは何かというと、FIDOアライアンスの資料を意訳すると下記のようになります。

FIDO標準に基づくパスキーは、パスワードに代わるもので、ユーザーのデバイスを横断して、ウェブサイトやアプリへのサインインをより迅速、簡単、かつ安全に行うことができる。パスワードとは異なり、パスキーは常に強固でフィッシングに強い。

パスキーは、アプリやウェブサイトのアカウント登録を簡素化し、使いやすく、ユーザーのほとんどのデバイスで機能し、物理的に近接した他のデバイスでも機能します。

この引用部ではちょっとわかりづらいのでまた別の資料を見てみると、FIDOアライアンスの過去の資料によるとPasskeyとは、マルチデバイス対応FIDO資格認証情報で、ユーザーのもつすべてのデバイスでFIDO認証資格情報を利用できるようにするものとあります。

マルチデバイス対応FIDO認証資格情報(マルチデバイスFIDOクレデンシャル。業界では非公式に「パスキー」とも呼ばれる)を導入し、ユーザーのもつすべてのデバイスでFIDO認証資格情報を容易に利用できるようにするものです。

3. Keycloak と Passkey

では Keycloak はPasskey についてKeycloakのリポジトリ内でPasskeyに関する情報を調べてみると、Issue や Pull requestsにはめぼしいものは見つかりませんでしたが、Support for passkey というDiscussion が見つかりました。

Disucussionの中を確認してみると、下記のようなコメントにあるようにコンディショナルUIはまだサポートしていないようですがKeycloakはPasskeyをサポート済みのようなのでこれを試していきます。

Keycloak supports Passkey, but there is room for improvement. WebAuthn Conditional UI is not yet supported. I have created the following discussion:

#15860

また下記のコメントのように、Passkeyのチュートリアルがあるようなのでこのチュートリアルについても見ていこうと思います。

Just stumbled upon the Keycloak Passkey tutorial which describes how passkeys support with decent UX can be implemented with current Keycloak.

The code of the extensions from the example can be found here: https://github.com/inventage/keycloak-custom/tree/tutorial-passkey

4. Keycloak のデフォルトでのPasskeyでの実装

ではまずデフォルトでのPasskeyの実装を見ていこうかと思います。 今回の検証では下記のような docker-compose.yml を用いていきます。

services:
  keycloak:
    container_name: keycloak
    image: quay.io/keycloak/keycloak:22.0.3
    entrypoint: ["/opt/keycloak/bin/kc.sh","start-dev"]
    ports:
      - "8088:8080"
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: password
      KC_LOG_LEVEL: debug

では下記のコマンドでコンテナを動かしておきましょう。 $ docker-compose up

また、レルム、クライアント、ユーザーは下記のようなデータを用いて検証していきます。

レルムのデータ

レルム名は下記の値とします。

レルムの作り方については公式ドキュメントをご参照ください。

フィールド
Realm namesample-realm

クライアントのデータ

下記のようにClient IDとValid redirect URIsのみを入力し、 それ以外の値はデフォルト値のままとします。

クライアントの作り方については公式ドキュメントをご参照ください。

フィールド
Client TypeOpenID Connect (defaultの値)
Client IDtest-client
Valid redirect URIshttps://client.example.com/test

ユーザーのデータ

ユーザーのデータについては下記のデータで作成します。

ユーザーの作り方については公式ドキュメントをご参照ください。

フィールド
Usernamecl-taro

また、ユーザーの Credentials については今回も下記のように作成します。

フィールド
Passwordpassword
TemporaryOff

4.1 フローの作成

では次は認証のフローの作成をしていきます。

1. まず作成したレルムにいることを確認して、Authentication タブに移動します。 

2. browser の "・・・" のアイコンから Duplicate を押します。

3. Name を WebAuthn Browser と入力して Duplicate を押します。

4. WebAuthn Browser Browser - Conditional OTP のゴミ箱アイコンを押してください。

5. 確認ウィンドウがでたら、Delete を押します。

6. WebAuthn Browser Forms +マークのメニューから、Add step を押します。

7. WebAuthn Authenticator のチェックボックスを入れて Add を押します。 (筆者の環境では3ページ目)

8. WebAuthn Authenticator の Requirement を押して、リストから Required に変更してください。

9. フローの修正の完成形は下記のイメージです。

4.2 作成したフローのバインド

フローを作成しただけだと、実際の挙動に結びついていないのでブラウザに関する箇所に紐づけてみます。

1. 先程作成したフローを開いた状態で、画面上部の Action から Bind flow を押します。 

2. Browser flow を選択して、Save を押します。


3. 保存を終えたあとに Autentication タブに戻ると、下記のように WebAuthn Browser の Used by の欄が Browser flow になっているのがわかります。 

4.3 初回登録・認証

では作成したフローでの認証の挙動を確認してみましょう。

1. 認可エンドポイント にアクセスしてみると下記の画像のようにログイン画面が表示されます。 

2. ユーザー名(cl-taro)とパスワード(password)を入力して、Sign in を押すと、下記のような画面が出ますので、Register を押します。

3. 下記のウィンドウが出るので 続行 を押します。 

4. 下記の画面がでたら Touch ID で認証を行いましょう。 

5. Touch ID で認証を行うと下記のようなラベルの設定のウィンドウが出るので、OK を押します。 

6. 認証が完了して下記のように リダイレクトURI に遷移してることがわかります。 

4.4 登録後の再ログイン

先程は初回登録時のフローを見たので、登録後の再ログイン時の挙動も見ていきます。

1. 再度シークレットウィンドウなどを起動して、認可エンドポイント にアクセスしてみます。 

2. ユーザー名(cl-taro)とパスワード(password)を入力して、Sign in を押すと、下記のような画面が出ますので、 Sign in with Security Key を押します。 

3. 下記のウィンドウが出るので 続行 を押します。

4. 下記の画面がでたら Touch ID で認証を行いましょう。 

5. 認証が完了して下記のように リダイレクトURI に遷移してることがわかります。 

5. Keycloak のチュートリアルでのPasskeyの確認

Support for passkey というDiscussion にあった、チュートリアルを次は見ていこうかと思います。

まずGithubのURLからみてみると、Githubの情報から見るに、これは inventage というオーガニゼーションの keycloak-customというリポジトリの、tutorial-passkey というブランチを指していそうです。

Inventage は社名であり、スイスのチューリッヒにある企業で、Webテクノロジーとオープンソースコンポーネントを使用して、デジタルバンキング関連などに個別のソリューションを実装している企業のようです

参考1: 公式サイト 参考2: twitter

チュートリアルのページについてもページのヘッダーには KEYCKLOAK COMPETENCE CENTER と記載はありますが、フッダーを確認すると、Inventage 社への情報が載っているので、このページ自体もInventage社が作っているように見えます。

Requirementsの箇所を確認すると、要件としては下記のように記載されています。

Requirements To complete our tutorial you need:

・ Operating System and Browser with Passkey support.

・ Install the following components:
  ・ Java JDK 11
  ・ Maven
  ・ Docker Host
  ・ jq

今回は指紋認証のできる、MacBook Pro で試したのですが、 Passkeyを対応したオペレーティングシステムとして、 OSはmacOS Ventura(13.3.1)を用いて検証しました。

また、ブラウザは Google chrome (117.0.5938.92)を用います。

上記を含めた環境に関しては下記のようになります。

対象種類・バージョン
OSmacOS Ventura(13.3.1)
ブラウザGoogle chrome (117.0.5938.92)
Java JDKopenjdk 20.0.1
MavenApache Maven 3.9.3

チュートリアルのページを見て、手順を確認します。

As for all projects based on our custom Keycloak template you need to execute the following 4 commands:

チュートリアルのページの上記を見る限り下記の4つのコマンドで構成できそうなので順に試していきます。

$ ./mvnw clean package
$ docker-compose -f ./docker-compose/postgres/docker-compose.yml up
$ ./server/run-keycloak.sh
$ ./server/run-keycloak-setup.sh

まずはソースの取得を行います。Githubのリポジトリは 'https://github.com/inventage/keycloak-custom.git' で、ブランチは 'tutorial-passkey' なので下記のようなコマンドになります。

ソースを取得したら、先程 clone したディレクトリに移動します。

  • $ cd keycloak-custom/

5.1 パッケージの生成

Maven ラッパーを使って、クリーンした後にJAR ファイルの作成をしていきます。

  • $ ./mvnw clean package

上記を実行すると、下記の結果が出力されます。

[INFO] parent ............................................. SUCCESS [  0.533 s]
[INFO] server ............................................. SUCCESS [  6.732 s]
[INFO] config ............................................. SUCCESS [  3.211 s]
[INFO] extensions ......................................... SUCCESS [  0.012 s]
[INFO] extension-passkey .................................. SUCCESS [  1.885 s]
[INFO] themes ............................................. SUCCESS [  0.105 s]
[INFO] container .......................................... SUCCESS [  0.977 s]
[INFO] docker-compose ..................................... SUCCESS [  0.276 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  13.982 s
[INFO] Finished at: 2023-09-28T10:06:00+09:00
[INFO] ------------------------------------------------------------------------

"BUILD SUCCESS" の表示もあるように、ビルドが成功していることがわかります。

5.2 Postgres の起動

では下記のコマンドで docker を用いて Postgres を起動します。

  • $ docker-compose -f ./docker-compose/postgres/docker-compose.yml up

下記のような出力がでており、起動が完了していそうかを確認してください。

postgres-postgres-1  | 2023-09-28 01:12:09.341 UTC [1] LOG:  database system is ready to accept connections

5.3 Keycloak の起動

次にカスタムされた Keycloak をローカル環境で起動します。

  • $ ./server/run-keycloak.sh

いくつかの出力の後で、下記のような出力がでてきたら起動が完了しています。

2023-09-28 10:14:07,132 WARN  [org.keycloak.quarkus.runtime.KeycloakMain] (main) Running the server in development mode. DO NOT use this configuration in production.

5.4 初期設定を行う

1. 上記で起動が確認できたら、 ローカルで起動したKeycloakの画面 にアクセスしてみましょう。 下記のような画面が表示されます。

2. "Administration Console"を押して、Admin Consoleを開いてみます。

3. Keycloakの初期の管理ユーザーとパスワードは下記になっているのでログインしてみます。

  • ユーザー: admin
  • パスワード: admin

4. 下記のようにまだ作成時点ではレルムもmasterしかありません。

4. 下記のように準備されているコマンドを実行し、必要なレルムやクライアントを作成してみます。

  • $ ./server/run-keycloak-setup.sh

少し待つといくつかの出力の後で、下記のような表示が出てきたらセットアップが完了しています。

--------------- KEYCLOAK SETUP FINISHED ----------------

では再度、Admin Console を開いてみてみます。下記のように turorial_passkey のレルムが作成されていれば設定は完了しています。

5.5 挙動を確認

KeycloakのWebサイトで提供されているテストアプリで動きを見てみましょう。

1. KeycloakのWebサイトを開きます。下記の画像のように初期値として KeycloakURLは http://localhost:8080 Realm は myrealm Client は myclient が入力されていますので、これを下記の値で書き換えて Save を押します。

FieldValue
Realmtutorial_passkey
Clientclient_passkey

チュートリアルのサイトの説明のページ では下記のような記述がありますが、これは間違えており ./config/src/main/resources/keycloak/setup/realm-passkey.json を見るとわかるように、Realmは tutorial_passkey Clientは client_passkey です。

It is worth noting that you have to change the realm to passkey_tutorial and the client to passkey_client as shown below:

2. RealmとClientを書き換えて、Save を押すと下記のように画面になるので "Sign in" を押してみます。 

3. Sign in を押したあと下記のようなログインするための入力フォームと "Continue" と "Sign in with Passkey" というボタンのある下記の画面が表示されます。 

4. まずはアカウントが登録されていないので、"Register" を選択すると下記のような画面が出るので、 それぞれの項目を下記の仮の値で埋めて "Register" を押します。

FieldValue
First nametaro
Last namecl
Emailcl-taro@example.com
Usernametaro

5. 下記のような パスワードかpasskeyの設定画面が出るので、 "Setup passkey" を押します。

6. 下記のページが出るので、"Register" を押します。

7. 下記のようなポップアップが出るので、今回は MacBook Pro で Touch ID を使うため このデバイス 押します。

8. 下記のポップアップにユーザー名の cl-taro が出ているので、"続行" を選びます。


9. 下記のようなポップアップが表示されるので、今回はMacBook Pro で Touch ID を使うため Touch ID センサー に指を合わせて指紋認証を行います。

10 下記のようなポップアップに切り替わるので、ラベル名を入力して "OK" を押してください。今回はデフォルト値である "WebAuthn Authenticator (Default Label)" のままで行きます。

11. 下記のようにログイン完了後の画面が出ます。ログインの挙動を確認するために、"Sign out"を押して、一度ログアウトしましょう。

12. 再度サインインするために、"Sign in" を押します。

13. 下記のようなログイン画面が出るので、"Sign in with Passkey" を選択します。

14. 下記のようなポップアップが出るので、"続行"を押します。

15. 指紋認証のポップアップに切り替わるので、MacBook Pro で Touch IDを用いた指紋認証を行います。

16. 下記のように無事ログインできることが確認できました。 

6. MacBook Pro + Google Chrome でのPasskeyの取り扱い

MacBook Pro で Google Chrome を用いたときのPasskeyの取り扱いについてですが、 Google ChromeヘルプでPasskeyの管理について確認すると下記のような記載があります。

パスキーの詳細 パスキーは暗号鍵ペアであるという点でパスワードとは異なります。鍵ペアは各ウェブサイトに固有のものです。ペアの片方はウェブサイトと共有されますが、もう片方は共有されずにデバイスまたはパスワード マネージャーに保存されます。

また、上記ドキュメントでは macOS での取り扱いについては下記のような記述があります。

macOS でパスキーを保存する パスキーを Chrome プロフィールに保存して、macOS キーチェーンで保護できます。

重要: Chrome では、iCloud キーチェーンにパスキーを保存したり、保存されているパスキーを使用したりすることはできません。パソコンを紛失した場合や Chrome プロフィールを削除した場合、パスキーを復元できません。

macOS でパスキーを管理する

  1. パソコンで Chrome を開きます。
  2. その他アイコン その他 次に [設定] 次に [自動入力] 次に [パスワード マネージャー] 次に [パスキーを管理] をクリックします。

上記の引用部のようにChromeの設定画面で確認してみます。Google chromeの設定画面を開くと下記のように保存されていることがわかりました。 

では、下記のように  のアイコンからPasskeyに関する情報を削除してみましょう。 

ログアウトした状態で、再度KeycloakのWebサイトの画面から "Sign in" を選び下記のログイン画面まで遷移します。

Passkey で Sign in するために、"Sign in with Passkey" を押してみると、ここまでの手順で登録したPasskeyの設定が見つからないため、下記のような表示になっていることがわかります。

7. あとがき

今回は Keycloakのデフォルトでの Passkey の実装と、Inventage社が公開している、Keycloak と Passkey に関するチュートリアルを試しつつ、UI周りやGoogleChromeでのPasskeyの管理などを簡単に見ていきました。

Passkeyの実装周りなどはまた別の記事でご紹介できればと思います。

新規CTA