🔑

ローカルで Related Origin Requests (ROR) を試した際のメモ

2024/12/22に公開

ローカルで Related Origin Requests (ROR) [1] を試してみたのでその際の手順を備忘録として残しておきます。
動作確認を行うにあたって、passkeys.dev[1:1] の Example に記載されている https://shopping.comhttps://shopping.co.uk というドメインを使用したシナリオに沿って再現しました[2]
また、実装としては以下のリポジトリのコードを利用しました。すでに Autofill UI が動作している状態でいくつか修正を加えることで動作させています。

https://github.com/kg0r0/passkey-autofill-example/tree/related-origins

RP 実装の変更点

主に RP に必要な変更は /.well-known/webauthn の実装です[3]。このとき、https://[RP ID]/.well-known/webauthn となるようにエンドポイントを実装します。レスポンスの形式は JSON であり、以下のように origins に有効なオリジンの配列を含めて返します。

{
  "origins": [
    "https://shopping.com",
    "https://myshoppingrewards.com",
    "https://myshoppingcreditcard.com",
    "https://myshoppingtravel.com",
    "https://shopping.co.uk",
    "https://shopping.co.jp",
    "https://shopping.ie",
    "https://shopping.ca"
  ]
}

なお、ブラウザが Related Origin Requests をサポートしているか事前にチェックすることができます[4]。これにより、クライアントの状況を踏まえたハンドリングを追加することができるでしょう。

        if (typeof PublicKeyCredential === 'undefined') {
          console.log("PublicKeyCredential is not supported in this browser.");
        }
        if (typeof PublicKeyCredential.getClientCapabilities === 'function') {
          let capabilities;
          try {
            capabilities = await PublicKeyCredential.getClientCapabilities();
            console.log(capabilities);
          } catch (error) {
            console.error('Error getting client capabilities:', error);
          }
          if (!capabilities.relatedOrigins) {
            console.log('Related Origin Requests (ROR) is not supported in this browser');
          }
        } else {
          console.log('getClientCapabilities is not supported in this browser');
        }

動作確認

動作確認をするうえでいくつか準備をおこないます。
まず、shopping.com および shopping.co.uk でローカルの RP にアクセスできるように /etc/hosts に以下の定義を追加します。

/etc/hosts
127.0.0.1	localhost shopping.com shopping.co.uk

また、WebAuthentication API の呼び出し時のオリジンとして localhost 以外を利用する場合、HTTPS かつ証明書エラーが発生しないようにする必要があります。
これについては、"Use HTTPS for local development"[5] に記載の手順を行うことで証明書エラーが発生しないようにローカルで HTTPS のサーバーを起動することができます。
例えば、今回に関しては、以下のコマンドを実行することで shopping.com+1-key.pem および shopping.com+1.pem が生成され、shopping.com および shopping.co.uk に証明書エラー無しでアクセスできるようになります。

$ mkcert  shopping.com  shopping.co.uk

(上記のコマンドによって生成された証明書を確認したところ、入力したオリジンに基づいて良い感じに SAN を指定してくれているようでした。)

$ openssl x509 -noout -text -in shopping.com+1.pem
  ...
            X509v3 Subject Alternative Name:
                DNS:shopping.com, DNS:shopping.co.uk
  ...

ここまでで動作確認をする準備ができたので実際に RP を起動してアクセスしてみます (前述の通り証明書などはご自身で用意してください)。

$ git clone -b related-origins https://github.com/kg0r0/passkey-autofill-example.git
$ cd passkey-autofill-example
$ ls certs
shopping.com+1-key.pem shopping.com+1.pem
$  go run .

まずは、shopping.co.uk にアクセスして Passkeys の登録を行います。

この時点で shopping.co.uk のサインインに先ほど登録した Passkeys が使えることがわかります。

次に、shopping.com にアクセスします。このとき RP ID として shopping.co.uk を指定して Web Authentication API を呼び出します。

ここで、従来であれば現在アクセスしているオリジンと RP ID のミスマッチにより Web Authentication API の呼び出しにおいてエラーが返されますが、以下のように https://[RP ID]/.well-known/webauthn に対してリクエストが行われていることが確認できます。

$ go run .
2024/12/22 18:29:13 INFO shopping.co.uk/.well-known/webauthn

最終的にサインインが完了することが確認できました。

なお、https://shopping.co.uk/.well-known/webauthn のレスポンスに含まれるオリジンから https://shopping.com を削除した場合、以下のようなエラーが発生してサインインが失敗することを確認しました。

SecurityError: The RP ID "shopping.co.uk" is invalid for this domain
    at error (index.umd.min.js:2:3961)
    at e.startAuthentication (index.umd.min.js:2:4289)
    at async login:47:22Caused by: SecurityError: The relying party ID is not a registrable domain suffix of, nor equal to the current domain. Subsequently, fetching the .well-known/webauthn resource of the claimed RP ID was successful, but no listed origin matched the caller.

今回はとりあえず Related Origin Requests (ROR) の動作を試してみました。

この記事を Digital Identity 技術勉強会 #iddance Advent Calendar 2024 9 日目の記事として、終わりたいと思います。ではまた!

https://qiita.com/advent-calendar/2024/iddance

脚注
  1. https://passkeys.dev/docs/advanced/reloated-origins/#deployment-considerations ↩︎ ↩︎

  2. https://passkeys.dev/docs/advanced/related-origins/#example ↩︎

  3. https://passkeys.dev/docs/advanced/related-origins/#relying-party-changes ↩︎

  4. https://passkeys.dev/docs/advanced/related-origins/#client-support ↩︎

  5. https://web.dev/articles/how-to-use-local-https ↩︎

GitHubで編集を提案

Discussion