Keycloak で試す WebAuthentication (WebAuthn) x OpenID Connect (OIDC)
Digital Identity 技術勉強会 #iddance Advent Calendar 2023 8 日目の記事です。
本投稿では、OpenID Connect (OIDC)[1] と Web Authentication (WebAuthn)[2] の関連性に触れつつ、Keycloak を Identity Provider (IdP) として使用してパスワードレスな認証を導入する考え方について記載します。
以下の記事で WebAuthn RP を実装する方法や Passkeys をサポートする方法を記載していますが、自ら WebAuthn RP を実装することなく WebAuthn を使用した認証を導入する方法があることを紹介できればと思います。
なお、本投稿では説明の都合上 WebAuthn および FIDO2 という用語が登場しますが、WebAuthn は FIDO2 仕様の一部であり、本投稿においては基本的に同じ用語を指しているものと考えていただいて問題ありません[3]。
Web Authentication (WebAuthn), a core component of FIDO Alliance’s FIDO2 set of specifications, is a web-based API that allows websites to update their login pages to add FIDO-based authentication on supported browsers and platforms.
(引用元: https://fidoalliance.org/fido2-2/fido2-web-authentication-webauthn/)
はじめに
まず、OIDC (や SAML) は ID 連携の仕様であり、FIDO との関連性は以下の通り補完関係となります[4]。
FIDO and federation protocols are not only complementary but function optimally together.
(引用元: https://fidoalliance.org/fido-and-federation-protocols-tech-note/)
OIDC と FIDO の関連性を図示すると例えば以下のようになります。
Initial ‘Sign-in’ with FIDO-based Authentication[4:1]
OIDC OP は OIDC のフローにおけるユーザー認証において WebAuthn を使用することができ、OIDC RP は OIDC OP が発行する ID Token を検証することでユーザーの認証結果や属性情報を受け取ることができます。
これにより、OIDC OP が WebAuthn RP として動作する場合、OIDC RP 自身が WebAuthn RP として動作しない場合もパスワードレスな認証を使用することができます。
本投稿では、OIDC OP および WebAuthn RP の機能を有している Keycloak を使用して前述の動作を実際に試してみます。
Keycloak のドキュメント[5]に記載の通り、Keycloak は WebAuthn RP として動作し Passkeys もサポートしています。
Passkeys
Keycloak provides preview support for Passkeys. Keycloak works as a Passkeys Relying Party (RP).
Passkey registration and authentication are realized by the features of WebAuthn. Therefore, users of Keycloak can do passkey registration and authentication by existing WebAuthn registraton and authentication.
(引用元: https://www.keycloak.org/docs/latest/server_admin/#passkeys_server_administration_guide)
なお、動作確認では下のリポジトリの実装を使用します。
基本的な設定がおこなわれた状態で起動するように実装しているため不明点などがあれば必要に応じてご確認ください。
設定
Keycloak にて OIDC RP の作成と WebAuthn の設定をそれぞれ行います。
OIDC
まずは以下のドキュメントの手順に従って OIDC RP を作成します。
設定値については、実際の OIDC RP の要件にもとづいて適切な値を指定してください。動作確認で使用する OIDC RP については、localhost で動作するウェブアプリケーションであるため以下のような設定にしています。
WebAuthn
次に以下のドキュメントを参照し、WebAuthn に関する設定をおこなっていきます。
特にパスワードレスな認証については、以下の "Passwordless WebAuthn together with Two-Factor" や "LoginLess WebAuthn" の手順が参考になります。
- Passwordless WebAuthn together with Two-Factor: https://www.keycloak.org/docs/latest/server_admin/#_webauthn_passwordless
- LoginLess WebAuthn: https://www.keycloak.org/docs/latest/server_admin/#_webauthn_loginless
なお、上記のドキュメントに記載の手順による設定は個人的に意図していた認証フローではなかったため、今回は以下のブログ[6]に記載の設定を使用しました。
Authentication flow の設定としては、Username Form
と WebAuthn Passwordless Authenticator
をそれぞれ Required としています。
上記の Authentication flow を Browser flow にバインドしています。
今回はユーザー自身に登録を行わせたいため User registration
を On にしておきます。
また、ユーザー登録時に認証器の設定も行わせたいため Webauthn Register Passwordless
を default action に設定します。
最後に Webauthn Passwordless Policy
を要件に合わせて設定します。ここでは、User verification requirement
を Required に設定しています。
動作確認
前述の設定を行った状態で起動する構成を用意したため、こちらを使用して動作を確認していきます。
$ git clone https://github.com/kg0r0/keycloak-oidc-rp.git
$ cd keycloak-oidc-rp
Keycloak の OpenID Connect Discovery Document はリクエスト時の URL に基づいた設定が返されます[7]。
このため Issuer の検証を成功させつつ WebAuthn API を localhost で呼び出すために以下の extra_hosts
の設定を行います。
version: "3.8"
services:
rp:
build: ./rp
ports:
- 3000:3000
depends_on:
- keycloak
extra_hosts:
- localhost:x.x.x.x # <= この部分をローカルマシンの IP アドレスに変更
keycloak:
build: ./keycloak
ports:
- 8080:8080
- 8443:8443
volumes:
- ./keycloak/import:/opt/keycloak/data/import
以下のコマンドを実行することで Keycloak (http://localhost:8080) および OIDC RP (http://localhost:3000) がそれぞれ起動します。
$ docker-compose build
$ docker-compose up -d
ここで http://localhost:8080 にアクセスしてユーザー名およびパスワードそれぞれ admin
でサインインして demo
レルムの設定を確認しておきます。
登録
まずは OIDC RP (http://localhost:3000/login) にアクセスして OIDC の認可コードフローを開始します。
このとき、Keycloak にリダイレクトされて以下の画面が表示されるため [Register]
を押下してユーザーの登録に進みます
登録画面でいくつかの情報の入力を要求されるため適宜入力して [Register]
を押下します。
ここで Security Key Registration の画面が表示されるため [Register]
を押下して登録を進めます。
WebAuthn API の実行によって以下のようなブラウザでダイアログが表示され、認証器の登録を進めることができます。
登録が完了すると OIDC のフローが再開され、OIDC RP にリダイレクトされたのちに OIDC RP は ID Token を取得します。
認証
まずは OIDC RP (http://localhost:3000/login) にアクセスして OIDC の認可コードフローを開始します。
先ほど登録した認証器を使用して認証をおこなうことができることが確認できます。
認証が行われると OIDC RP にリダイレクトされ、ID Token を検証したのちにユーザーの属性情報が画面上に表示されます。
おわりに
本投稿では、OpenID Connect (OIDC) と Web Authentication (WebAuthn) の関連性に触れつつ、Keycloak を Identity Provider (IdP) として使用してパスワードレスな認証を導入する方法を紹介しました。
OIDC などの ID 連携の仕様を組み合わせることで、自ら WebAuthn の RP を実装することなく WebAuthn による認証をサービスに導入することができます。このため、WebAuth による認証をサービスに導入することを考える場合、利用する IdP にどういった機能が実装されているかを確認し、どのような方法で導入するのが最適か検討することが重要かもしれません。
ではまた!
-
OpenID Connect Core 1.0 incorporating errata set 1 | https://openid.net/specs/openid-connect-core-1_0.html ↩︎
-
Web Authentication: An API for accessing Public Key Credentials Level 3 | https://www.w3.org/TR/webauthn-3/ ↩︎
-
FIDO2: Web Authentication (WebAuthn) | https://fidoalliance.org/fido2-2/fido2-web-authentication-webauthn/ ↩︎
-
FIDO TechNotes: Is FIDO Intended to Replace Federation Protocols? | https://fidoalliance.org/fido-and-federation-protocols-tech-note/ ↩︎ ↩︎
-
Server Administration Guide | https://www.keycloak.org/docs/latest/server_admin/ ↩︎
-
FIDO2 Passwordless Authentication With Keycloak - Part 2 | https://refactorfirst.com/setup-fido2-passwordless-authentication-with-keycloak ↩︎
-
Configuring the hostname | https://www.keycloak.org/server/hostname ↩︎
Discussion