Apple Touch ID Keyboard を使ったパスワードレス認証
庄司です。弊社では隔月で有志によるハッカソンを開催しています。
1 月のハッカソンで、私は年が明けてすぐに購入した「Appleシリコン搭載Macモデル用Touch ID搭載Magic Keyboard - 英語(US)」を、昨年公開した記事「WebAuthn でパスワードの無い世界へ」の通りに利用することをテーマに参加しました。
試してみたところ、いくつか課題が見つかりました。
旧記事の通りに進めようとした場合の課題は次の通りです。
- Apple シリコンに対応した最新の Keycloak をインストールできない。
- 最新と古いバージョン間でパスワードレス認証を有効にする画面が (微妙に) 異なる。
さらに今回は Kubernetes で動作するようにしたいとも考えました。
旧記事「WebAuthn でパスワードの無い世界へ」では、Keycloak のコンテナイメージを Docker Hub から取得していました。しかし、最新の Keycloak コンテナイメージは Quay.io で公開されています。
この記事で紹介する Helm チャートのイメージの指定も Docker Hub ではなく Quay.io から pull するようになっています。
Keycloak
#Keycloak は SAML の Identity Provider (IdP) としてあるいは OpenID Connect (OIDC) の OpenID Provider (OP) として使用できる認証プロダクトです。クラウド環境やオンプレミス環境で使用可能です。
前提
#動作確認に使用した環境は次の通りです。
- Apple Silicon (M1) mac mini
- Rancher Desktop 1.7.0
- Kubernetes 1.23.13
インストール
#Keycloak のインストール
#Helm チャートを使ってインストールします (ArtifactHUB)。
この記事では Rancher Desktop に同梱されている Ingress である traefik を使用します。
そのため SSL/TLS 証明書が必要になります。
この記事では証明書を Let's Encrypt で取得します。
certbot
#Homebrew を使って certbot をインストールします。
brew install certbot
証明書生成
#次のコマンドを実行します。
sudo certbot certonly --manual --preferred-challenges dns
ドメイン名を入力します。所有するドメイン名が example.com
であれば、*.example.com
のように入力すると便利です。
Please enter in your domain name(s) (comma and/or space separated) (Enter 'c'
to cancel):
ドメイン名の所有を確認するために、DNS に TXT レコードの追加が要求されます。
表示された指示に従って DNS (Route 53 等) に TXT レコードを追加します。
_acme-challenge.example.com TXT "<表示された値>"
DNS にレコードを追加してから、それがローカル環境で認識されるまで少し時間がかかるので、追加後しばらく待ってから Enter キーを押してください。
成功すると、この例であれば /etc/letsencrypt/live/example.com
ディレクトリに証明書ファイルが生成されます。
Helm コマンドを使ったインストール
#Helm チャートリポジトリにあるオリジナルの values.yaml に若干変更が必要です。
オプション、Ingress を有効にするための変更を加えた values.yaml
ファイルを GitHub リポジトリに置いています。takesection/keycloak-install を clone してください。
git clone https://github.com/takesection/keycloak-install.git
cd keycloak-install
certbot で生成されたファイルをクローンした keycloak-install
にコピーします。
sudo cp /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/live/example.com/privkey.pem ./
tls-secret
を作成します。
kubectl create secret tls tls-secret --cert=fullchain.pem --key=privkey.pem
values.ymlの編集
#values.yml
から local-values.yml
をコピーしてください。
cp values.yml local-values.yml
local-values.yml
の298行目、306行目にある ingress の設定を、証明書のドメイン名に合わせて編集します。例えば、使用するドメイン名が keycloak.example.com
であれば、次のようになります。
# List of rules for the Ingress
rules:
-
# Ingress host
host: '{{ .Release.Name }}.example.com'
# Paths for the host
paths:
- path: /
pathType: Prefix
# TLS configuration
tls:
- hosts:
- keycloak.example.com
secretName: "tls-secret"
Helm チャートのリポジトリを追加します。
helm repo add codecentric https://codecentric.github.io/helm-charts
helm コマンドを使ってインストールします。
helm install keycloak --values=local-values.yml codecentric/keycloak
Keycloak の初期設定
#port-forward で localhost でアクセスできるようにします。
kubectl port-forward svc/keycloak-http 8080:80
ブラウザを使って http://localhost:8080/auth/
にアクセスして、管理者のユーザ名とパスワードを設定します。
Create
ボタンをクリックします。
パスワードレス認証フローの設定
#Administration Console
のリンクをクリックして、Username or email
と Password
には、それぞれ先に設定した管理者のユーザ名、パスワード を入力して Sign In します。
新しい Realm を作成するため、左上の Master のあたりにマウスを置いて「Add realm」ボタンをクリックします。
Add realm の Name に passengers
と入力し、「Create」ボタンをクリックします。
左側にある Authentication
をクリックします。
Flows の設定
#- Flows で
Browser
を選択し、右にある「Copy」ボタンをクリックします。
- 新しい名前として
WebAuthn Browser
と入力し、「Ok」ボタンをクリックします。
- WebAuthn Browser Forms の下にある「Username Password Form」、「WebAuthn Browser Browser - Conditional OTP」、「Condition - User Configured」と「OTP Form」の右にある
Actions
からDelete
を選んで削除します。
- WebAuthn Browser Forms の右にある
Actions
のAdd execution
をクリックして、Provider
からUsername Form
を選択して「Save」ボタンをクリックします。
- WebAuthn Browser Forms の右にある
Actions
のAdd flow
をクリックしてAlias
にPassword Or Two-factor
を入力して「Save」ボタンをクリックします。このフローはREQUIRED
に設定します。
- Password Or Two-factor の右にある
Actions
のAdd execution
をクリックして、Provider
からWebAuthn Passwordless Authenticator
を選択して「Save」ボタンをクリックします。このフローはALTERNATIVE
に設定します。
- Password Or Two-factor の右にある
Actions
のAdd execution
をクリックしてProvider
からPassword Form
を選択して「Save」ボタンをクリックします。このフローはALTERNATIVE
に設定します。
ここまでの設定で WebAuthn Browser
は次のようになります。
Bindings
#Bindings タブをクリックして Browser Flow
に WebAuthn Browser
を選択して「Save」ボタンをクリックします。
Required Actions
#Required Actions タブをクリックして「Register」ボタンをクリックし、Required Action に Webauthn Register Passwordless
を選択して「Ok」ボタンをクリックします。
WebAuthn Passwordless Policy
#WebAuthn Passwordless Policy タブをクリックします。
この画面では、次のように入力して「Save」ボタンをクリックします。
項目名 | 値 |
---|---|
Relying Party Entity Name | keycloak |
Signature Algorithms | ES256 |
Relying Party ID | 構築した keycloak の DNSName |
Attestation Conveyance Preference | none |
Authenticator Attachment | platform |
Require Resident Key | No |
User Verification Requirement | discouraged |
Timeout | 0 |
Avoid Same Authenticator Registration | OFF |
Acceptable AAGUIDs |
試してみましょう
#左側の Manage にある Users
をクリックします。
「Add user」ボタンをクリックします。
「Username」、「Email」、「First Name」、「Last Name」を入力し「Save」ボタンをクリックします。
Credentials タブをクリックします。
Set Password にパスワードを入力し「Set Password」ボタンをクリックします。
認証情報の登録
#kubectl get ingress
で表示されたホスト名とIPアドレスを /etc/hosts
ファイルに設定します。
https://{ホスト名}/auth/realms/passengers/account
に Chrome ブラウザでアクセスします。
-
「Sign In」ボタンをクリックします。
-
Username or email に作成したユーザの Username か Email を入力して「Sign In」ボタンをクリックします。
-
Password を入力して「Sign In」ボタンをクリックします。
- Password の変更が求められたら、変更します。
-
リンク
Signing In
をクリックします。 -
Passwordless
、Security Key
のリンクSet up Security Key
をクリックします。
- 「Register」ボタンをクリックします。
- デバイスに Touch ID が登録されます。
パスワードレスでログイン
#Sign Out して、もう一度 Sign In をクリックします。
Password を入力する画面の下のリンク Try Another Way
をクリックします。
リンク Security Key
をクリックします。
「Sign in Security Key」ボタンをクリックして、Touch ID で認証します。
おわりに
#昨年記事を書いた時点では Apple 社のブラウザ Safari 以外ではパスワードレス認証ができなかったと記憶しています。この記事にある通り、今では Google Chrome ブラウザでも Touch ID に対応したパスワードレス認証ができています。