🐈

Safari 18で Automatic Passkey Upgrades をやってみた

2024/09/23に公開

はじめに

Safari 18 で Automatic Passkey Upgrades っていうのができるらしいということで、どんなものか使ってみたメモです。

https://www.corbado.com/blog/ios-18-passkeys-automatic-passkey-upgrades

環境

  • macOS Sequoia 15.0
  • Safari 18.0

Automatic Passkey Upgrades とは?

macOS Sequoia, iOS 18 では Appleのパスワードマネージャー が追加されました。このアプリで パスワードを自動的にパスキーにアップグレードする機能です。

つまり、パスキーを自動で作る仕組みです。

今までは、パスワードでログインしてから「パスキーを作る」って操作をして、指紋とか顔認証とかしてパスキーを作るやり方でした。


パスキーを作成するときのTouch ID認証

Automatic Passkey Upgradesでは、パスワードでログインしたら 自動でパスキー作っちゃう ってことができるみたいで、パスワード認証をやめてパスキー認証に移行してほしいRPにとっては、魅力的なものなんじゃないかと感じました。


Appleのパスワードマネージャー


パスワードマネージャの画面

自動でパスキー作るって、どうやるの?

RP側での実装が必要です。でも結構簡単です。

パスキーを作るときは JavaScript で navigator.credentials.create() ってAPIを使うんですけど、このとき渡すOptionに

"mediation": "conditional"

ってつけるだけです。

こうすると、TouchIDなどでユーザーの確認をすることなく、即座にパスキーを作成することができます。

特記事項は以下のとおり

  • パスキーは Appleのパスワードマネージャー に作成される
  • 内部的にチェックがあって、OKとなったらパスキーが作成される
    • 例えば、ログインするときに、パスワードマネージャ経由でパスワード入力してないとだめ
    • それ以外にも色々チェックがありそう
  • パスキー作成結果の UserPresentUserVerified フラグは false になる
    • つまり、ユーザーの存在確認も、本人確認もしないでパスキー作ったってこと
    • 今までのパスキー作成では 「UserPresentUserVerified フラグが true なのかちゃんとチェックしましょう」というのが普通だったと思うんですけど、チェックしないようにする必要があります。

Appleのパスキーは確かパスキーの証明書に相当するAttestaionがなかったような気がするので、ユーザー確認もAttestationのVerifyもなしでパスキー作るでオッケーとするかどうかはRPで要検討ってことになりそうです。

やってみる

ログイン後の画面に Automatic Passkey Upgradesってボタンを置いて、これをクリックしたらAutomatic Passkey Upgradesの手順でパスキーを作成してみようと思います。

Automatic Passkey Upgrades に対応しているかどうかチェックする

未対応のブラウザでは実行されないようにチェックする処理を実装します。

こちらのサンプル のようにチェックします。

https://github.com/gebogebogebo/spring-boot-3-passkey-webauthn4j/blob/90cd034f72aeadc948918cf6d1f0974487e51842/src/main/resources/static/js/index.js#L43-L71

パスキー作成オプションに mediation をつける

navigator.credentials.create() に 渡す Option に mediation をつけます。

https://github.com/gebogebogebo/spring-boot-3-passkey-webauthn4j/blob/90cd034f72aeadc948918cf6d1f0974487e51842/src/main/resources/static/js/index.js#L212-L217

うまくいくと、即座にレスポンスが返ってくるので、それをそのままサーバーに渡してVerifyします。

サーバーでVerifyする

サーバーサイドは webauthn4j(0.26.0.RELEASE) を使いました。

webauthn4j では パスキーの作成結果を Veirfy する際に RegistrationParameters を渡すんですけど、ここに考慮を加える必要があります。

https://github.com/gebogebogebo/spring-boot-3-passkey-webauthn4j/blob/90cd034f72aeadc948918cf6d1f0974487e51842/src/main/kotlin/com/example/springwebauthn4j/service/webauthn4j/WebAuthn4JServerServiceImpl.kt#L145-L153

今回のパスキー作成結果は UP, UV が false なので、そういうものでもVerifyを通るようにします。

https://github.com/gebogebogebo/spring-boot-3-passkey-webauthn4j/blob/90cd034f72aeadc948918cf6d1f0974487e51842/src/main/kotlin/com/example/springwebauthn4j/service/webauthn4j/WebAuthn4JServerServiceImpl.kt#L218-L227

以上で 自動でパスキーを作成することができました。パスキー作成時はユーザーへのポップアップや通知が一切ありませんでしたので、「Youはパスキー認証ができるようになったよ」などとユーザーに通知する仕組みは別途実装するほうが良さそうです。

実装の悩みどころ...

  • 通常のパスキー作成は UP, UV が true であることを必須にしたいので、Automatic Passkey Upgradesと通常のパスキー作成をサーバー側で判別したほうがよさそう
  • パスワード認証をパスした後にパスキーを作成するために一旦フロントに制御を戻すのがめんどくさそう

やってみたメモ

パスキーが作成できるケース

以下の条件を満たしていると、この方法でパスキーを作成できました。

  • Appleのパスワードマネージャーにユーザ名とパスワードが登録されていて、パスキーは作成されていない
  • ログインするときに、Appleのパスワードマネージャー経由でユーザー名とパスワードを入力してログインした

パスキー作成できないケース

以下の場合はエラーになってパスキーが作成できませんでした。

  • Appleのパスワードマネジャを使わないでログインした場合
    • 手入力でユーザー名とパスワードを入力してログインして、パスキーを自動作成しようとしてもエラーになります。
  • 既にパスキーを作成済みの場合
  • パスワードマネージャで「自動でパスキーを作成」のチェックをOFFにしている場合
    • パスワードマネージャの設定メニューから設定できます。私の環境ではデフォルトでONでした。

まとめ

ユーザーにパスワード認証をやめてパスキー認証に移行してもらうのはとても大変である、という現状があるかと思います。

パスキー推進のための実装に工数かかってどうしようもないとかあるんで、こういう方法があってもいいかなと思いました。

ちなみに、Automatic Passkey Upgrades は
W3CのWebAuthn仕様(Editor’s Draft, 18 September 2024)
5.1.3. Create a New Credential
にのっているようです。他のブラウザでも実装されてくると、かなりパスキーの導入が進めやすくなると感じました。

今回のサンプルソースはこちら

GitHub: spring-boot-3-passkey-webauthn4j の safari18-passkey-upgradesブランチ

Discussion