1. はじめに
このセクションは規定ではありません。
ウェブサイトへのサインインは、本来よりも難しくなっています。ユーザーエージェントは体験を様々な面で改善できる特別な立場にあり、ほとんどの最新のユーザーエージェントはブラウザにネイティブな形で何らかのcredential managementを提供することでこれを認識しています。たとえば、ユーザーはウェブサイトのユーザー名やパスワードを保存でき、それらの 資格情報 は後にサインインフォームへ自動入力されますが、成功度合いは様々です。
属性
autocomplete
は宣言的な仕組みを提供し、ウェブサイトが特定のフィールドを "username" や "password"
としてマークすることで、ユーザーエージェントがサインインフォームを検出して入力する能力を向上させるために連携できます。ユーザーエージェントは、マークアップでこの詳細を提供していないサイトに対して動作するために、さまざまな検出ヒューリスティックを実装しています。
このヒューリスティックと宣言的検出の組み合わせは比較的よく機能しますが、検出が問題になる大きなギャップが残っています。一般的でないサインイン方式(例えば、資格情報をXMLHttpRequest経由で送信するケース)のサイトは確実に検出するのが難しく、ユーザーがフェデレーションIDプロバイダを使って認証したいというケースが増えていることも同様です。ウェブサイトがユーザーエージェントの
資格情報マネージャ
とより直接的にやり取りできるようにすれば、一方で資格情報マネージャの精度を高め、他方でフェデレーテッドサインインを利用するユーザーを支援できるようになります。
これらのユースケースは § 1.1 Use Cases および Credential Management: Use Cases and Requirements により詳しく説明されています;この仕様書は、ウェブサイトがユーザーの 資格情報 を要求し、ユーザーが正常にサインインした際にユーザーエージェントへ資格情報の永続化を依頼できる Credential Manager API を定義することで、その文書が列挙する多くの要件に対応しようと試みています。
Note: ここで定義する API は意図的に小さく単純です:それ自体で認証を提供することを目的とせず、既存のユーザーエージェントによって実装されている 資格情報マネージャ へのインターフェイスを提供することに限定しています。この機能は、ベンダーや著者の双方に大きな労力を要求することなく、今すぐに価値があります。もちろんさらに多くのことが可能ですが、ここではいくつかの考えを § 9 Future Work に残しており、将来の API の反復で検討される可能性があります。
1.1. ユースケース
現代のユーザーエージェントは、ウェブサイトへのサインイン時にパスワードを保存できる機能や、ユーザーが再訪した際にサインインフォームへ自動または半自動でパスワードを入力する機能を備えています。ウェブサイト側から見ると、この動作は完全に不可視です:パスワードが保存されたことも、フォームに入力されたこともサイトは知りません。これは良い面も悪い面もあります。一方では、ユーザーエージェントのパスワードマネージャーはサイトの協力がなくても機能し、ユーザーにとって有益です。もう一方では、パスワードマネージャーの動作は、サインインフォームやパスワード変更フォームの検出などを目的とした脆弱で独自のヒューリスティックの寄せ集めになっています。
現状の課題として、特に以下の点が挙げられます:
-
ユーザーエージェントはフェデレーテッドIDプロバイダーによるユーザー支援が非常に困難です。ユーザー名/パスワードフォームの検出は比較的容易ですが、サードパーティによるサインインの検出は確実に行うのが難しいです。ウェブサイトが典型的なフェデレーテッドサインインのリダイレクトの意図をユーザーエージェントに伝えられれば理想的です。
-
同様に、ユーザーエージェントは単純なユーザー名/パスワードフォーム以外の特殊なサインイン手法の検出に苦労しています。著者は
XMLHttpRequestなどを使って非同期的にサインイン処理を行うことが増えています。これはユーザーにとって良い体験ですが、ユーザーエージェントのパスワードマネージャーへの統合は困難です。ウェブサイトが独自のサインイン方式についてユーザーエージェントに伝えられれば理想的です。 -
最後に、パスワード変更は、ウェブサイトが明示的に認証情報の変更をユーザーエージェントに通知すれば、より良いサポートが可能です。
2. コアAPI
開発者視点では、認証情報とは、特定の操作に対して認証判断を行うためのオブジェクトです。本セクションでは、Credential
インターフェースをベースクラスとして定義します。これは本仕様や他の仕様書で定義される認証情報の基盤となり、navigator.credentials.*
にぶら下がるAPI群から取得できます。
各種認証情報タイプは、それぞれJavaScript上で、継承によって、直接的または間接的にCredential
インターフェースを基盤としています。本仕様書では、PasswordCredential
とFederatedCredential
の2つを定義しています。その他、例えば[WEBAUTHN]では他の認証情報タイプが定義されています。
認証情報が特定のオリジンに有効であるとは、そのオリジンで認証として受理されることを指します。認証情報がある時点で有効であっても、UAは同じ認証情報が将来的にも有効だと仮定できない理由がいくつかあります:
-
パスワード認証情報は、アカウント保有者がパスワードを変更した場合、有効でなくなる可能性があります。
-
SMSで受け取ったトークンで作成された認証情報は、1回限りの利用のみ有効な場合が多いです。
使い捨て認証情報は、認証情報ソースによって生成されます。これは秘密鍵、フェデレーテッドアカウントへのアクセス、特定の電話番号でSMS受信できる能力などであり、JavaScriptで直接扱うことはできず、本仕様でも明示的に表現されません。モデルを統一するため、パスワード自体も認証情報ソースと見なし、これをコピーしてパスワード認証情報を作成します。
UAは、有効な認証情報が再度有効であるとは限らない、あるいは有効な認証情報を生成した認証情報ソースが将来も有効な認証情報を生成できるとは限らないものの、後者の方が可能性として高いです。過去に有効だった認証情報をstore()
で記録すれば、UAは今後ユーザーに提示する際、より有効な認証情報ソースを提供できる可能性が高まります。
2.1. インフラストラクチャ
A credential manager は、保存、整理、管理し、資格情報の選択を可能にする アプリケーション、ハードウェア機器、またはサービスです。資格情報マネージャの例としては、 デジタルウォレット、パスワードマネージャ、およびpasskeyマネージャが含まれます。
ユーザーエージェントは内部的にcredential storeを提供しなければなりません(MUST)。これは、どのcredentialsがeffectiveであったかを記録する、 ベンダー固有の不透明な格納機構です。これは、credentialへのアクセスと永続化に対して次の機能を提供します:
-
Store a credential — 後で取得できるようにcredentialを保存します。これは credential storeに挿入します。
-
Retrieve a list of credentials — 任意のフィルタを受け取り、フィルタに一致するcredentialsの集合を返します。
-
Modify a credential — credentialを受け取り、既存のcredentialの状態を上書きして credential store内の状態を更新します。
さらに、credential storeは、オリジンごとにprevent silent access
flagを維持するべきです(特に指定がない限りtrueに設定されます)。
そのフラグがtrueに設定されている場合、そのオリジンはrequires user
mediationとなります。
Note: ユーザー媒介の重要性については、§ 5 User Mediationでより詳しく議論されています。
Note: credential storeは、 ユーザーエージェントが本書で指定したAPIを実装する際の内部実装の詳細であり、ウェブに対して直接公開されるものではありません。 特定のcredentialタイプをサポートするために、 他の文書でより多くの機能が指定される場合があります。
本書は、そのアルゴリズムと本文で使用される多くの基礎概念について Infra Standard に依存しています [INFRA]。
各environment settings objectには、関連付けられたアクティブな資格情報タイプがあり、これは初期状態では空の集合です。
2.1.1. インフラストラクチャアルゴリズム
2.1.1.1. 祖先も同一オリジンであること
環境設定オブジェクト(settings)が祖先も同一オリジンであるかどうかは、以下のアルゴリズムがtrueを返す場合です:
-
settingsの関連グローバルオブジェクトに関連付けられたDocumentがなければ、
falseを返す。 -
documentをsettingsの関連グローバルオブジェクトの関連付けられたDocumentとする。
-
documentにブラウジングコンテキストがなければ、
falseを返す。 -
originをsettingsのオリジンとする。
-
navigableをdocumentのノードナビゲーブルとする。
-
navigableが非nullの親を持つ間:
-
navigableをnavigableの親にする。
-
navigableのアクティブドキュメントのオリジンがoriginと同一オリジンでなければ、
falseを返す。
-
-
trueを返す。
2.1.2. 認証情報タイプレジストリ
このレジストリは認証情報タイプ(例:[[type]]値)を、指定された認証情報タイプに関連する様々な値へマッピングします。例えば、オプションメンバー識別子(正式には辞書メンバーの識別子)は、CredentialCreationOptionsやCredentialRequestOptions(すなわち「オプション辞書」)で仕様ごとに使われます。
注: このレジストリは関連する認証情報インターフェースオブジェクトアルゴリズムで利用されます。
| 認証情報タイプ (アルファベット順) | オプションメンバー識別子 | 適切なインターフェイスオブジェクト | 取得パーミッションポリシー | 作成パーミッションポリシー | 同一get()
リクエストで許可されるタイプ
| 仕様書 | 申請者連絡先 |
|---|---|---|---|---|---|---|---|
| digital-credential | digital | DigitalCredential
| digital-credentials-get | null | empty | [DIGITAL-CREDENTIALS] | WICG |
| federated | federated | FederatedCredential
| null | null | password | 本仕様書: § 4 フェデレーテッド認証情報 | W3C |
| identity | identity | IdentityCredential
| identity-credentials-get | null | empty | [FEDCM] | W3C |
| otp | otp | OTPCredential
| otp-credentials | null | empty | [WEB-OTP] | WICG |
| password | password | PasswordCredential
| null | null | federated | 本仕様書: § 3 パスワード認証情報 | W3C |
| public-key | publicKey | PublicKeyCredential
| publickey-credentials-get | publickey-credentials-create | empty | [WEBAUTHN] | W3C |
2.1.2.1. 登録エントリ要件および更新プロセス
-
各レジストリエントリは、辞書メンバーの識別子(レジストリ内ではオプションメンバー識別子と呼ばれる)を、認証情報仕様の
CredentialCreationOptionsおよびCredentialRequestOptions拡張で使用されるものとして記載しなければなりません。 -
各レジストリエントリは、適切なインターフェイスオブジェクトの 識別子を 認証情報タイプごとに記載しなければなりません。
-
各レジストリエントリは、取得パーミッションポリシーとなる パーミッションを Credentialのリクエストを 認証情報タイプに対して行う際に使用するものとして記載しなければなりません。 パーミッションポリシーが指定されていない場合はnullとします。
-
各レジストリエントリは、作成パーミッションポリシーとなる パーミッションを Credentialの作成を 認証情報タイプに対して行う際に使用するものとして記載しなければなりません。 パーミッションポリシーが指定されていない場合はnullとします。
-
get()のリクエストでは1つのリクエストで複数タイプを問い合わせることが可能ですが、 すべての組み合わせが許可されるわけではありません。各レジストリエントリにはセットとしての 認証情報タイプ を記載し、 その同一get()リクエストで許容されるタイプ を示さなければなりません。 他と混在できない場合はemptyを記載します。 いずれの認証情報タイプもget()リクエストで自身とは混在可能です。 -
各レジストリエントリの仕様には申請者の連絡先情報を含めなければなりません。
このレジストリの更新は、認証情報タイプの登録エントリの追加、変更、または削除です。 どなたでもwebappsec-credential-management レポジトリへのPull Requestによって本レジストリの更新を申請できます。 Web Applications Security Working Groupは次回以降の会議アジェンダに追加し、 申請者へ通知します。 申請に対する検討と対応はW3C Web Applications Security Working Groupの合意により行われます。 議長は結果を申請者に知らせ、必要に応じてレジストリが更新されます。
2.2.
Credentialインターフェース
[Exposed =Window ,SecureContext ]interface {Credential readonly attribute USVString id ;readonly attribute DOMString type ;static Promise <boolean >isConditionalMediationAvailable (); };
id、型は USVString、読み取り専用-
認証情報の識別子。この識別子の要件は、各credentialの種類ごとに異なります。例えば、ユーザー名/パスワードの組ではユーザー名を表す場合があります。
type、型は DOMString、読み取り専用-
この属性のgetterは、オブジェクトのインターフェースオブジェクトの
[[type]]スロットの値を返します。これは、このオブジェクトが表す認証情報タイプを指定します。 isConditionalMediationAvailable()-
Promiseを返し、ユーザーエージェントがconditionalな認証情報要求の仲介を 認証情報タイプに対してサポートしている場合のみtrueで解決し、そうでない場合はfalseで解決します。CredentialのisConditionalMediationAvailable()のデフォルト実装:conditionalな仲介をサポートする認証情報タイプ用の仕様では、 この関数をtrueでresolveするように明示的にオーバーライドしなければなりません。注: この関数が存在しない場合は、
conditionalな仲介はその認証情報タイプ ではサポートされません。 [[type]]-
Credentialインターフェースオブジェクトは[[type]]という名前の内部スロットを持ちます。ここには 認証情報タイプを表す文字列 が格納されます。規定がない限り、この値は空文字列です。 §2.1.2 認証情報タイプ・レジストリで 認証情報タイプ一覧を参照してください。注:
[[type]]スロットの値は、特定のインターフェースを実装する全ての credential で同じになるため、 開発者はobj.typeが 特定のCredential種類を明確に表す文字列を返す、ということに依存できます。 [[discovery]]-
Credentialインターフェースオブジェクトは[[discovery]]という名前の内部スロットを持ちます。 これはユーザーエージェントが特定の認証情報タイプをどのように収集できるかという仕組みを表します。 その値は "credential store" または "remote" のいずれかです。前者は 利用可能なすべての認証情報がユーザーエージェントのcredential storeに 保管されていることを意味し、後者はユーザーエージェントが何らかの外部デバイスやサービスと連携してcredential storeに明示的に表現されていない認証情報を発見できることを意味します。
TobieやDominicと、 インターフェースオブジェクトの扱いについて ここや§2.5.1 Credentialのリクエストなどで相談すること。用語の使い方が正しくないかもしれない。 インターフェースプロトタイプオブジェクトかもしれない?
一部のCredential
オブジェクトはオリジンバウンドです。これらは
[[origin]]
という内部スロットを持ち、
そこにはこのCredential
が有効となりうる
オリジン
を保存します。
2.2.1.
Credentialの内部メソッド
Credential
インターフェースオブジェクトには、内部メソッドがいくつか備わっており、
Credential
オブジェクトの取得や保存を支援します。各メソッドは、本節以下に示すデフォルトの「何もしない(no-op)」実装を持ちます。
特に明記されていない限り、Credential
を継承するインターフェース用に作られる各インターフェースオブジェクトは、
少なくとも下記内部メソッドのいずれか1つ以上の実装を持たなければなりません(MUST)。
必要に応じてCredentialの
デフォルト実装をオーバーライドしてください。その認証情報型にふさわしいものとすること。
例:§ 3.2 PasswordCredential インターフェース、§ 4.1 FederatedCredential インターフェース、
[WEBAUTHN]
など。
2.2.1.1. [[CollectFromCredentialStore]]内部メソッド
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
は、オリジン、CredentialRequestOptions、
およびブール値を受け取って呼び出されます。このブール値は、呼び出し元の環境設定オブジェクトが祖先と同一オリジンである場合にのみ
true です。
アルゴリズムは、指定されたオプションに一致するユーザーエージェントの認証情報ストアからCredential
オブジェクトの集合を返します。一致するCredential
オブジェクトが存在しない場合、返される集合は空になります。
Credentialの
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
のデフォルト実装:
-
空集合を返す。
2.2.1.2. [[DiscoverFromExternalSource]]内部メソッド
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
は、並列で、オリジン、CredentialRequestOptions
オブジェクト、
そして呼び出し元の環境設定オブジェクトが
祖先と同一オリジンの場合にのみ true となるブール値で呼ばれます。
指定されたオプションで返すことができる場合はCredential
を返し、
利用可能な認証情報がなければ null を返し、発見に失敗した場合(例えば無効なオプションなど)はエラーをスローします(例:TypeError)。
この種類のCredential
が単回利用や期間限定の場合、
このメソッドは認証情報ソースを使って新しい認証情報を生成する責任を負います。
Credential
の
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
のデフォルト実装:
-
nullを返す。
2.2.1.3. [[Store]]内部メソッド
[[Store]](credential, sameOriginWithAncestors)
は、並列で、Credential
と、
呼び出し元の
環境設定オブジェクトが祖先と同一オリジンである場合にのみ true となるブール値で呼び出されます。
アルゴリズムは、Credential が
認証情報ストアに永続化された時点で完了します。
Credentialの
[[Store]](credential, sameOriginWithAncestors)
のデフォルト実装:
-
NotSupportedErrorをスローする。
2.2.1.4. [[Create]]内部メソッド
[[Create]](origin, options, sameOriginWithAncestors)
は、並列で呼び出され、オリジン、CredentialCreationOptions、
および呼び出し元の
環境設定オブジェクトが祖先と同一オリジンの場合のみ
true となるブール値を受け取ります。
このアルゴリズムは:
-
Credentialを生成する、または -
認証情報を生成せず、
nullを返す、または -
異常な状況(例:無効なオプションによる
TypeErrorなど)の場合はエラーをスローする。
Credentialを作成する場合は、
グローバルオブジェクトを受け取って
インターフェースオブジェクト
(Credentialから継承)
を返すアルゴリズムを返します。
このアルゴリズムはタスクから呼び出されなければなりません。
注: このアルゴリズムの手順は認証情報タイプごとに定義されています。
Credentialの
[[Create]](origin, options, sameOriginWithAncestors)
のデフォルト実装:
-
nullを返す。
2.2.2.
CredentialUserDataミックスイン
一部の Credential
オブジェクトには、ユーザーが認証情報選択UIで判別しやすくするための、表示用の名前やアイコン画像のデータが含まれています:
[SecureContext ]interface mixin {CredentialUserData readonly attribute USVString name ;readonly attribute USVString iconURL ; };
name、型は USVString、読み取り専用-
この認証情報に紐付いた名称。認証情報選択UIでユーザーに分かりやすい名前として表示されることを意図しています。
iconURL、型は USVString、読み取り専用-
この認証情報用の画像のURL。認証情報選択UIで表示することを意図しています。このURLは信頼できる可能性のあるURLでなければなりません。
2.3.
navigator.credentials
開発者は Credential
を取得し、
ユーザーエージェントの 認証情報ストア とやり取りするには、
CredentialsContainer
インターフェースに公開されているメソッドを利用します。
このインターフェースは Navigator
オブジェクト配下の
navigator.credentialsとして提供されます。
partial interface Navigator { [SecureContext ,SameObject ]readonly attribute CredentialsContainer credentials ; };
credentials 属性は、
アクティブドキュメントの閲覧コンテキストに関連付けられている
CredentialsContainer
を返さなければなりません。
注: § 6.3 非保護サイトでも述べられている通り、 認証情報管理APIは セキュアコンテキストでのみ公開されます。
[Exposed =Window ,SecureContext ]interface {CredentialsContainer Promise <Credential ?>get (optional CredentialRequestOptions options = {});Promise <undefined >store (Credential credential );Promise <Credential ?>create (optional CredentialCreationOptions options = {});Promise <undefined >preventSilentAccess (); };dictionary {CredentialData required USVString ; };id
get(options)-
get()が呼び出されたとき、ユーザーエージェントは 「Credentialのリクエスト」 をoptionsに対して実行した結果を返さなければなりません。CredentialsContainer.get(options) メソッドの引数 パラメーター 型 Nullable Optional 説明 optionsCredentialRequestOptions✘ ✔ リクエストの範囲を決定するプロパティの集合。 store(credential)-
store()が呼び出されたとき、ユーザーエージェントは 「Credentialの保存」をcredentialに対して実行した結果を返さなければなりません。CredentialsContainer.store(credential) メソッドの引数 パラメーター 型 Nullable Optional 説明 credentialCredential✘ ✘ 保存する認証情報。 create(options)-
create()が呼び出されたとき、ユーザーエージェントは 「Credentialの作成」をoptionsに対して実行した結果を返さなければなりません。CredentialsContainer.create(options) メソッドの引数 パラメーター 型 Nullable Optional 説明 optionsCredentialCreationOptions✘ ✔ Credentialの作成に用いるオプション。 preventSilentAccess()-
preventSilentAccess()が呼び出されたとき、ユーザーエージェントは 「サイレントアクセスの防止」 を現在の設定オブジェクトに対して実行した結果を返さなければなりません。注記: ここでの目的はオリジンからの「サインアウト済み」シグナルです。 つまり、「サインアウト」ボタンのクリック後、サイトはユーザーのセッション情報を更新し、
navigator.credentials.preventSilentAccess()を呼びます。 これにより サイレントアクセス防止フラグ がセットされ、 次回ユーザーが訪問した際に認証情報が自動でページに返されないことを意味します。注記: この関数は以前
requireUserMediation()という名称でしたが、 これは非推奨とみなすべきです。
Navigator
オブジェクト(navigator)が作成されるとき、ユーザーエージェントは
navigator の 関連する Realm を使って
新しい CredentialsContainer
オブジェクトを生成し、navigator に関連付けなければなりません。
2.3.1. CredentialRequestOptions辞書
Credential
をget()
で取得するには、呼び出し元は
CredentialRequestOptions
オブジェクトでいくつかのパラメータを指定します。
注記:
CredentialRequestOptions
辞書は拡張ポイントです。
新しいタイプの認証情報がオプションを必要とし導入される場合、その辞書型がこの辞書に追加され、リクエストに渡せるようになります。
詳しくは§ 8.2 拡張ポイントを参照してください。
dictionary {CredentialRequestOptions CredentialMediationRequirement mediation = "optional";DOMString uiMode ;AbortSignal signal ; };
mediation、型は CredentialMediationRequirement。 省略時は"optional"。-
このプロパティは、特定の認証情報リクエストにおけるメディエーション要件を指定します。 それぞれの列挙値の意味は下記
CredentialMediationRequirementで説明されます。処理の詳細は§ 2.5.1 Credentialのリクエストに定義されています。 uiMode、型は DOMString-
このプロパティは、ユーザーエージェントがユーザーメディエーションを実行する際の、 特定の認証情報リクエストのユーザーインタフェースモードを指定します。 それぞれの値の意味は下記
CredentialUiModeで説明されます。処理の詳細は§ 2.5.1 Credentialのリクエストで定義されています。 signal、型は AbortSignal-
このプロパティにより、開発者は進行中の
get()操作を中断できます。中断された操作は(一般的に完了後に中断が届いた場合は)正常終了することもあれば、 中断理由 でリジェクトされることもあります。
unmediatedメンバーが定義されていました。
これをtrueにすると
mediation
が
"silent"
になり、falseにすると
mediation
が
"optional"
になる効果がありました。
unmediatedは非推奨と考えるべきであり、新しいコードは
mediation
に依存すべきです。
CredentialCreationOptions
や
CredentialRequestOptions
(options)に対して以下のように収集される
インタフェースオブジェクトの集合です。
注記: このアルゴリズムはCredential Type Registryを使用します。
-
settingsを 現在の設定オブジェクト とする。
-
各 options の optionKey → optionValue について:
-
credentialInterfaceObjectを、適切なインターフェイスオブジェクト (settingsのグローバルオブジェクト上)で オプションメンバー識別子が optionKeyであるもの、とする。
-
アサート: credentialInterfaceObject の
[[type]]スロット値は、Credential Type(オプションメンバー識別子 がoptionKeyであるもの)と等しい。 -
credentialInterfaceObjectを relevant interface objects に追加する。
-
-
relevant interface objects を返す。
CredentialRequestOptions
(options)は、
以下の手順がtrueを返す場合、
事前にマッチ可能
です。
-
optionsの該当する認証情報インタフェースオブジェクト 内の各interfaceについて:
-
interfaceの
[[discovery]]スロット値が "credential store" でなければ、falseを返す。
-
-
trueを返す。
注記:
get(options)
の実行時、指定された
CredentialRequestOptions
が
事前にマッチ可能
な場合のみ、ユーザーメディエーションなしで認証情報を返します。
外部サービス(OAuthトークンやセキュリティキー認証器など)から発見を必要とするタイプがリクエストされた場合、
検出処理のため(IdPやBTLEデバイスの選択など)ユーザーメディエーションが必要となります。
2.3.2. メディエーション要件
get(options)
やcreate(options)
でリクエストする際、開発者は
適切なCredentialMediationRequirement
の列挙値を選んで
ユーザーメディエーション
要否を個別に設定できます。
注記: § 5 ユーザーメディエーション の章にて、この概念全般やユーザーエージェントがオリジンごとのリクエストにどう応じるかの影響がより詳しく解説されています。
enum {CredentialMediationRequirement "silent" ,"optional" ,"conditional" ,"required" };
silent-
指定した操作でユーザーメディエーションを抑制します。ユーザーの関与なしに実行可能ならそれでよいですが、関与が必要ならユーザーを煩わせず
nullを返します。注記: 開発者がユーザーを自動的にサインインさせたいとき、サインインプロンプトで邪魔せずサイレントに認証情報が得られればよい、 「このサイトにサインインしたままにする」シナリオ のための指定です。
optional-
認証情報がユーザーメディエーションなしで引き渡せる場合はそのまま引き渡し、ユーザーメディエーションが必要な場合はユーザーエージェントが ユーザーに確認します。
注記: これは
get()のデフォルトで、 たとえば「サインイン」ボタンを押した直後でユーザーもサインインしようとしているとき必要に応じて 認証情報選択ダイアログ が出ても驚かせたり困惑させたりしないことを想定しています。 conditional-
get()の場合、発見された認証情報はユーザーに対し非モーダルダイアログで、認証情報を求めている オリジンを示しつつ提示されます。 ユーザーがダイアログ外を操作した場合、ダイアログは閉じられ、呼び出し元に解決も拒否もせず ユーザーに見えるエラーにもなりません。ユーザーが認証情報を選択した場合はそれを返します。 サイレントアクセス防止フラグ は実際の値に関係なくtrueとして扱われ、conditional指定時は該当する認証情報が発見された場合必ず ユーザーメディエーションが行われます。該当する認証情報が見つからなければ、ユーザーエージェントは、そのタイプに応じた方法(例: デバイスの挿入など)で操作を促すことができます。 どちらの場合も、
get()がnullで即座に解決して 該当する認証情報がないとサイトに明かしてはいけません。Webサイトは、参照する 認証情報インタフェースすべて が
isConditionalMediationAvailable()をオーバーライドしてPromiseでtrueがresolveされる場合のみconditionalをget()に渡せます。create()の場合、ユーザーが以前に認証情報作成に同意し、直前にユーザーエージェントが認証を媒介していれば、 追加のモーダルな対話なしにcreate()が解決しても構いません。 直前に認証を媒介していないか、作成同意がない場合、呼び出しは "NotAllowedError"DOMExceptionをスローしなければなりません。 required-
requiredを指定した場合、サイレントアクセス防止フラグ が未セットであっても ユーザーメディエーションなしには 認証情報を引き渡しません。注記: この要件は再認証や ユーザー切替シナリオの想定です。 また、この要件は個々の操作に対するもので サイレントアクセス防止フラグ 自体には影響しません。フラグを設定するには
preventSilentAccess()を呼んでください。
2.3.3. UIモード
get(options)
でリクエストする際、開発者は
希望するユーザーメディエーションモードを
適切なCredentialUiMode
の列挙値を指定して表現できます。
UI Modeフィールドには既定値はありません。値が指定されていなければ、
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)メソッドが
CredentialMediationRequirement
のみを考慮してユーザーエージェントの動作を決定しなければなりません。
注記:
これにより呼び出し元は
ユーザーメディエーション
が発生する場合に異なるUI形式を区別できます。
UIの表示有無は、そのリクエストの
CredentialMediationRequirement
値に依存します。
すべてのCredentialUiMode
の値を、すべての
CredentialMediationRequirement
値と自由に組み合わせて意味があるとは限らず、
その組み合わせの動作は、各認証情報タイプがサポートする
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
メソッドに依存することになります。
enum {CredentialUiMode "immediate" };
immediate-
get()呼び出し時、ユーザーエージェントはモーダルな認証情報選択ダイアログをユーザーに表示するか、 認証情報を一切提供せず直ちに処理を完了させます。これにより、シンプルなサインインUIをユーザーに提示したり、 Webサイト側で独自のサインイン画面を出すなど、未サインインで続行する対応もできます。
認証情報選択ダイアログ内に表示できる認証情報が存在しない場合は ユーザーメディエーション は(たとえば認証情報入力の促しなどをせずに)スキップされます。
注記: この仕様は
isConditionalMediationAvailable()のようなimmediateのフィーチャー有無を検出する静的メソッドは提供しません。 将来このメディエーションモードが他の認証情報タイプにも拡張される場合は、 指定されたCredentialMediationRequirementやCredentialUiModeの組み合わせごとに何の認証情報タイプがサポートされるか判別できる、より汎用的なフィーチャー検出手法が必要となるでしょう。
2.3.3.1. 例
get()
を呼び出し、
mediation
メンバーに
"silent"を指定して渡します。
これにより、
§ 5.2 ユーザーメディエーションの要求
で説明したように、
ユーザーメディエーションなしのサインインに同意しているユーザーはそのままサインインされ、
同意していないユーザーは状況が分からずに
認証情報選択ダイアログ
が不用意に表示されて困ることがありません。
window.addEventListener('load', async () => {
const credentials = await navigator.credentials.get({
...,
mediation: 'silent'
});
if (credentials) {
// Hooray! Let's sign the user in using these credentials!
}
});
document.querySelector('#sign-in').addEventListener('click', async () => {
const credentials = await navigator.credentials.get({
...,
mediation: 'optional'
});
if (credentials) {
// Hooray! Let's sign the user in using these credentials!
}
});
注記: MegaCorp, Inc.は
mediation
メンバー自体を省略してもかまいません。なぜなら"optional"
がデフォルト値だからです。
get()
の
mediation
に
"required"を指定して、ユーザーエージェントが必ず
メディエーションを求めるようにできます。
注記: ブラウザや認証情報タイプのセキュリティモデルにより、この呼び出しにはユーザー自身が何らかの認証(マスターパスワード入力や指紋認証など)が必要になる場合があります。
document.querySelector('#important-form').addEventListener('submit', async () => {
const credentials = await navigator.credentials.get({
...,
mediation: 'required'
});
if (credentials) {
// Verify that |credentials| enables access, and cancel the submission
// if it doesn't.
} else {
e.preventDefault();
}
});
get()
で
mediation
メンバーに
"required"
を設定し、「アカウント追加」ボタンを押しても認証情報が自動的には返されないようにできます。
document.querySelector('#switch-button').addEventListener('click', e => {
var c = await navigator.credentials.get({
...,
mediation: 'required'
});
if (c) {
// Sign the user in using |c|.
}
});
2.4. CredentialCreationOptions辞書
Credential
を create()
で作成するには、呼び出し側は
CredentialCreationOptions
オブジェクトでいくつかのパラメーターを指定します。
注: CredentialCreationOptions
辞書は拡張ポイントです。新しい種類の認証情報が導入された場合、その辞書型がこの辞書に追加され、作成時に渡せるようになります。
詳細は§ 8.2 拡張点および本ドキュメントで導入される拡張(
§ 3.2 パスワード認証情報インターフェース・
§ 4.1 フェデレーテッド認証情報インターフェース)を参照してください。
dictionary {CredentialCreationOptions CredentialMediationRequirement = "optional";mediation AbortSignal signal ; };
signal、型は AbortSignal-
このプロパティにより、開発者は進行中の
create()操作を中断できます。 中断された操作は通常通り完了(多くの場合は操作終了後に中断が発生)するか、abort reason で reject されます。
2.5. アルゴリズム
2.5.1. Credentialの要求
Credential のリクエストアルゴリズムは、
CredentialRequestOptions
(options) を受け取り、資格情報を明確に取得できればそれで解決される Promise
を返します。明確な取得ができない場合はnullで解決されます。
-
settingsを現在の設定オブジェクトとする。
-
アサート: settingsはセキュアコンテキストである。
-
documentをsettingsの関連するグローバルオブジェクトの 関連付けられたDocumentとする。
-
もしdocumentが完全にアクティブでない場合は、拒否状態のpromise "
InvalidStateError"DOMExceptionを返す。 -
options.の中止されている場合、 拒否状態のpromise をsignaloptions.の 中断理由で返す。signal -
interfacesをoptionsの該当する認証情報インタフェースオブジェクトとする。
-
もしinterfacesが空なら、 拒否状態のpromise "
NotSupportedError"DOMExceptionを返す。 -
各interface1 of interfacesについて:
-
type1をinterface1の
[[type]]とする。 -
各interface2 of interfacesについて:
-
type2をinterface2の
[[type]]とする。 -
もしtype1 が type2と等しい場合は続行。
-
もしtype1の同一get()リクエストで許容されるタイプに type2が含まれていないなら、 拒否状態のpromise "
NotSupportedError"DOMExceptionを返す。
-
-
-
各interface of interfacesについて:
-
もしoptions.
mediationがconditionalであり、かつinterfaceがconditionalユーザーメディエーション に非対応なら、拒否状態のpromiseTypeErrorを返す。 -
もしoptions.
uiModeがimmediateであり、かつinterfaceがimmediateユーザーメディエーション に非対応なら、拒否状態のpromiseTypeErrorを返す。 -
もしsettingsの有効な認証情報タイプが interfaceの
[[type]]を含んでいる場合、 拒否状態のpromise "NotAllowedError"DOMExceptionを返す。 -
interfaceの
[[type]]をsettingsの 有効な認証情報タイプ に追加する。
-
-
originをsettingsのオリジンとする。
-
sameOriginWithAncestorsを、settingsが祖先と同一オリジンなら
true、そうでなければfalseとする。 -
optionsの該当する認証情報インタフェースオブジェクトの各interfaceについて:
-
permissionをinterfaceの
[[type]]の 取得パーミッションポリシー とする。 -
もしpermissionがnullなら続行。
-
もしdocumentが permissionの使用を 許可されていない場合は 拒否状態のpromise "
NotAllowedError"DOMExceptionを返す。
-
-
pを新しいpromiseとする。
-
次の手順を並行して実行する:
-
credentialsを認証情報ストアから
Credentialを収集(引数:origin、 options、sameOriginWithAncestors) の結果とする。 -
次のすべてが真ならpを credentials[0]で解決し、残りの手順をスキップする:
-
credentialsのサイズが1
-
originがユーザーメディエーションを必要としない
-
optionsが事前にマッチ可能である。
-
options.
mediationが "conditional"でない。
このモデルは正しくないかもしれません。たとえば、パスワード認証・webauthn型のどちらでも受け付けるが、前者だけなら選択ダイアログを省略してサインインしたい等が実現できると便利かもしれません。
-
-
resultをユーザーに
Credentialの選択を求める (引数:optionsとcredentials)の結果とする。 -
もしresultがインタフェースオブジェクトなら:
-
resultを resultの
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)(引数:origin、options、sameOriginWithAncestors) の実行結果にする。この実行で例外がスローされた場合:
-
スローされた例外をeとする。
-
タスクをキューイング し、globalの DOM 操作タスクソース で以下を実行:
-
p をeで拒否する。
-
-
これ以降の手順を終える。
-
-
-
アサート: resultは
nullまたはCredentialである。 -
もしresultが
Credentialであれば、 pをresultで解決する。 -
もしresultが
nullで、かつoptions.mediationがconditionalで なければ、 pをresultで解決する。注記: options.
mediationがconditionalで、nullの認証情報が発見された場合、promise pは解決されません。
-
-
-
各interface of interfacesについて:
-
interfaceの
[[type]]を settingsの 有効な認証情報タイプ から除去する。
-
-
-
pを返す。
2.5.2. 認証情報ストアからCredentialを収集
オリジン(origin)、
CredentialRequestOptions
(options)、
および 呼び出し元コンテキストが祖先と同一オリジン
(sameOriginWithAncestors)の場合にだけ true となるブール値が与えられたとき、
ユーザーエージェントは
認証ストアから Credential
を収集
できる。この操作は、ユーザーエージェントがローカルに保存している中から options のフィルタに合致する Credential
オブジェクトの集合を返す。そのような Credential
オブジェクトが存在しない場合、返される集合は空となる:
-
possible matches を空集合とする。
-
options の 関連資格情報インターフェースオブジェクト の各 interface について:
-
r を、interface の
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)内部メソッドを origin, options, sameOriginWithAncestors で実行した結果とする。それが例外を投げた場合は、その例外を再スローする。 -
アサート: r はインターフェースオブジェクトのリストである。
-
r の各 c について:
-
set append 操作で c を possible matches に追加。
-
-
-
possible matches を返す。
2.5.3. Credentialの保存
Credentialを保存するアルゴリズムは
Credential
(credential) を受け取り、
認証情報ストアへの保存が完了した時に解決される
Promise
を返します。
-
settingsを現在の設定オブジェクトとする。
-
アサート: settingsはセキュアコンテキストである。
-
もしsettingsの関連するグローバルオブジェクトの 関連付けられたDocumentが 完全にアクティブでなければ、 拒否状態のpromise "
InvalidStateError"DOMExceptionを返す。 -
sameOriginWithAncestorsを 現在の設定オブジェクトが 祖先と同一オリジンなら
true、 そうでなければfalseとする。 -
pを新しいpromiseとする。
-
もしsettingsの有効な認証情報タイプが credentialの
[[type]]を含んでいる場合、 拒否状態のpromise "NotAllowedError"DOMExceptionを返す。 -
credentialの
[[type]]をsettingsの 有効な認証情報タイプ に追加する。 -
次の手順を並行して実行:
-
credentialのインターフェースオブジェクトの
[[Store]](credential, sameOriginWithAncestors)内部メソッドを credentialおよびsameOriginWithAncestorsを引数に実行する。この実行で例外がスローされた場合:
-
スローされた例外をeとする。
-
タスクをキューイング し、 globalの DOM 操作タスクソース で以下のサブステップを実行:
-
p を e で拒否する。
-
成功時は p を
undefinedで解決する。 -
-
-
-
credentialの
[[type]]を settings の 有効な認証情報タイプ から除去する。
-
-
pを返す。
2.5.4. Credentialの作成
Credentialを作成するアルゴリズムは、
CredentialCreationOptions
(options) を受け取り、
指定されたoptionsで作成できる場合は
Promise
をCredential
とともにresolveし、
ひとつもCredential
を作成できない場合はnullでresolveします。
例外的な状況では、
Promise
は適切な例外でrejectされることがあります。
-
settings を 現在の設定オブジェクトとする。
-
アサート: settings は セキュアコンテキストである。
-
global を settings の グローバルオブジェクトとする。
-
document を 関連するグローバルオブジェクトの 関連付けられたDocumentとする。
-
もし document が 完全にアクティブ でない場合、 拒否状態のPromise "
InvalidStateError"DOMExceptionを返す。 -
sameOriginWithAncestors を、 現在の設定オブジェクト が 祖先と同一オリジンなら
true、 そうでなければfalseとする。 -
interfaces を セット として options の 該当する認証情報インターフェースオブジェクトを得る。
-
以下のどれかが該当する場合、拒否状態のPromise
NotSupportedErrorを返す:-
global に 関連付けられたDocument が存在しない。
-
interfaces の サイズ が1より大きい。
注記: 将来的にはこの制約を緩和して、 ユーザーエージェントが複数の候補となる認証情報タイプからユーザー操作で1つを選ぶ「サインアップ」用途などをサポートできるかもしれません。 現時点では、辞書を1エントリに制限することで対応を先送りしています。
-
-
interfaces 内の各 interface について:
-
permission を interface の
[[type]]の 作成パーミッションポリシー とする。 -
もし permission が null なら続行。
-
もし document が 許可されていない permission の使用、 拒否状態のPromise "
NotAllowedError"DOMExceptionを返す。
-
-
options.が 中断されているなら 拒否状態のPromise をsignaloptions.の 中断理由 で返す。signal -
type を interfaces[0] の
[[type]]とする。 -
もし settings の 有効な認証情報タイプ が type を 含んでいれば、 拒否状態のPromise "
NotAllowedError"DOMExceptionを返す。 -
type を settings の 有効な認証情報タイプ に追加する。
-
origin を settings の オリジンとする。
-
p を 新しいPromise とする。
-
次の手順を 並行して 実行:
-
r を interfaces[0] の
[[Create]](origin, options, sameOriginWithAncestors)内部メソッド(引数: origin, options, sameOriginWithAncestors) の実行結果とする。それが 例外なら:
-
スローされた 例外 を e とする。
-
タスクをキューイングし、 global の DOM操作タスクソースで以下のサブステップを実行:
-
p を e で拒否する。
-
-
これ以降のサブステップを終了する。
-
-
もし r が
Credentialまたはnullなら、 p を r で解決し、残りのサブステップを終了する。 -
アサート: r は(§ 2.2.1.4 [[Create]] 内部メソッド で定義された)アルゴリズムである。
-
タスクをキューイングし、 global の DOM操作タスクソース で以下を実行:
-
pを promise-calling r(引数:global)の結果で解決する。
-
-
-
-
type を settings の 有効な認証情報タイプ から取り除く。
-
-
p を返す。
2.5.5. サイレントアクセスの防止
サイレントアクセス防止アルゴリズムは、
環境設定オブジェクト(settings)を受け取り、
Promise
を返します。このプロミスはサイレントアクセス防止フラグが
認証情報ストアに永続化された時点で解決されます。
-
origin を settings の オリジン とする。
-
もし settings の 関連するグローバルオブジェクト の 関連付けられたDocument が 完全にアクティブ でなければ、 拒否状態のPromise "
InvalidStateError"DOMExceptionを返す。 -
p を 新しいPromise とする。
-
次の手順を 並行して 実行する:
-
origin の サイレントアクセス防止フラグ を 認証情報ストア に設定する。
-
p を
undefinedで解決する。
-
-
p を返す。
3. パスワード認証情報
良いか悪いかは別として、多くのウェブサイトは認証手段としてユーザー名/パスワードの組み合わせに依存しています。
PasswordCredential
インターフェースは、このユースケースを実現するための認証情報であり、ユーザー名とパスワード両方を保存し、
認証情報選択画面でユーザーが正しいアカウントを選びやすくするメタデータも保持します。
3.1. 例
3.1.1. パスワードによるサインイン
navigator.credentials.get()
を用いて
ユーザーの認証情報ストアから
ユーザー名/パスワードのペアを取得できます:
navigator.credentials .get({ 'password': true }) .then(credential => { if (!credential) { // このサイト用の認証情報をユーザーが持っていない、もしくは // 共有を拒否した。ここに基本的なログインフォームに // フォールバックするコードを挿入する。 return; } if (credential.type == 'password') { var form = new FormData(); form.append('username_field', credential.id); form.append('password_field', credential.password); var opt = { method: 'POST', body: form, credentials: 'include' // クッキーを送信 }; fetch('https://example.com/loginEndpoint', opt) .then(function (response) { if (/* |response| はログイン成功を示す */) { // 認証情報が有効であったことを記録する。下の注記参照。 navigator.credentials.store(credential); // サインイン成功をユーザーに通知し、サインイン済みの // 体験に遷移するなどの処理を行う! // 例えば location.href = '/signed-in-experience' で // ランディングページに遷移するなど } else { // ここにログインフォームへフォールバックするコードを挿入する。 } }); } });
または、Webサイト側で単に認証情報データを
form
にコピーしてformに対して
submit()
を呼び出すこともできます:
navigator.credentials .get({ 'password': true }) .then(credential => { if (!credential) { return; // 上と同様... } if (credential.type === 'password') { document.querySelector('input[name=username_field]').value = credential.id; document.querySelector('input[name=password_field]').value = credential.password; document.getElementById('myform').submit(); } });
前者の方法(store()を明示的に呼び出して認証情報を保存する)は
圧倒的に推奨されます。
form
ベースの仕組みはフォーム送信のタイミングで
閲覧コンテキストの遷移が発生し、サインイン成功後に
store()
を必ず呼び出せる保証がなくなるからです。
注記: ユーザーエージェントが表示する
認証情報選択ダイアログでは、
実際には現在のオリジンに保存されていない認証情報を
選択することもできます。たとえば
https://m.example.comの認証情報が
https://www.example.comへの
サインイン時に提示される(§ 6.1 クロスドメイン認証情報アクセス参照)、
あるいはユーザーがその場で新規認証情報を作成できる場合もあります。
このような不確定な状況にも対応できるよう、認証情報が
正しく使われたら(たとえ直前に
get()
で取得していた場合でも) 毎回
store()
を呼びだすことを推奨します。
認証情報がオリジンにまだ保存されていない場合は保存の案内が表示され、
すでに保存されていれば案内は行われません。
3.1.2. サインイン後の確認
サインイン成功後に新しい認証情報の保存をユーザーに提案するには、その認証情報をstore()
に渡します。
fetch()でサインインエンドポイントに認証情報を送信した場合、レスポンスでサインイン成功を確認し、ユーザーエージェントに通知できます。例えば次のようなサインインフォームの場合:
<form action="https://example.com/login" method="POST" id="theForm"> <label for="username">ユーザー名</label> <input type="text" id="username" name="username" autocomplete="username"> <label for="password">パスワード</label> <input type="password" id="password" name="password" autocomplete="current-password"> <input type="submit"> </form>
フォーム送信は次のようなハンドラで処理できます:
document.querySelector('#theForm').addEventListener('submit', e => {
if (window.PasswordCredential) {
e.preventDefault();
// "submit"イベント発火元のPasswordCredentialを
// HTMLFormElementから生成
// "username"や"current-password"のautocomplete属性値を吸い上げる
var c = new PasswordCredential(e.target);
// フォームのaction URLに新しい認証情報オブジェクト(FormData)を送信。成功ならユーザーエージェントに通知してパスワード保存を提案:
var opt = {
method: 'POST',
body: new FormData(e.target),
credentials: 'include' // クッキー送信
};
fetch(e.target.action, opt).then(r => {
if (/* |r| が"成功した" Response */)
navigator.credentials.store(c);
});
}
});
3.1.3. パスワード変更
この保存機構は「パスワード変更」にもそのまま利用できます。ユーザーが認証情報を変更した場合、ウェブサイトは新しい認証情報でサインイン成功を通知できます。ユーザーエージェントは保存済み認証情報を更新します:
store()を呼ぶことで認証情報更新可能です。
パスワード変更フォーム例:
<form action="https://example.com/changePassword" method="POST" id="theForm"> <input type="hidden" name="username" autocomplete="username" value="user"> <label for="password">新しいパスワード</label> <input type="password" id="password" name="password" autocomplete="new-password"> <input type="submit"> </form>
フォーム送信は次のように処理できます:
document.querySelector('#theForm').addEventListener('submit', e => {
if (window.PasswordCredential) {
e.preventDefault();
// "submit"イベント発火元のPasswordCredentialを
// HTMLFormElementから生成
// "username"や"new-password"のautocomplete属性値を吸い上げる
var c = new PasswordCredential(e.target);
// フォームのaction URLに新しい認証情報オブジェクト(FormData)を送信。成功ならユーザーエージェントに通知してパスワード保存を提案:
var opt = {
method: 'POST',
body: new FormData(e.target),
credentials: 'include' // クッキー送信
};
fetch(e.target.action, opt).then(r => {
if (/* |r| が"成功した" Response */)
navigator.credentials.store(c);
});
}
});
3.2.
PasswordCredentialインターフェース
[Exposed =Window ,SecureContext ]interface :PasswordCredential Credential {constructor (HTMLFormElement );form constructor (PasswordCredentialData );data readonly attribute USVString password ; };PasswordCredential includes CredentialUserData ;partial dictionary CredentialRequestOptions {boolean =password false ; };
password, 型 USVString, 読み取り専用-
認証情報のパスワードを表します。
[[type]]-
PasswordCredentialのインターフェースオブジェクトは[[type]]という内部スロットを持ち、その値は"password"です。 [[discovery]]-
PasswordCredentialのインターフェースオブジェクトは[[discovery]]という内部スロットを持ち、その値は"credential store"です。 PasswordCredential(form)-
このコンストラクターは
HTMLFormElement(form)を受け取り、以下の手順を実行します:-
originを現在の設定オブジェクトのoriginとする。
-
rをHTMLFormElementから
PasswordCredentialを作成(form、origin)の結果とする。
-
PasswordCredential(data)-
このコンストラクターは
PasswordCredentialData(data)を受け取り、以下の手順を実行します:-
rをPasswordCredentialDataから
PasswordCredentialを作成(data)の結果とする。
-
PasswordCredential
オブジェクトはPasswordCredentialData
辞書を明示的に渡すか、HTMLFormElementの
送信可能要素の内容に基づいて
navigator.credentials.create()
で作成できます。
dictionary :PasswordCredentialData CredentialData {USVString ;name USVString ;iconURL required USVString ;origin required USVString ; };password typedef (PasswordCredentialData or HTMLFormElement );PasswordCredentialInit partial dictionary CredentialCreationOptions {PasswordCredentialInit ; };password
PasswordCredential
オブジェクトはオリジンに束縛されます。
PasswordCredentialの
インターフェースオブジェクトはCredentialの
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
の実装を継承し、
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)、
[[Create]](origin, options, sameOriginWithAncestors)、
[[Store]](credential, sameOriginWithAncestors)
を独自実装します。
3.3. アルゴリズム
3.3.1.
PasswordCredentialの
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
は、オリジン(origin)、CredentialRequestOptions
(options)、
および 祖先と同一オリジン
かどうかを示すブール値(sameOriginWithAncestors)が true の場合に呼び出されます。
このアルゴリズムは認証情報ストアから Credential
オブジェクトの集合を返します。一致する Credential
オブジェクトがなければ返される集合は空になります。
アルゴリズムは sameOriginWithAncestors が true でない場合、NotAllowedError
例外を投げます。
-
もし sameOriginWithAncestors が
falseなら、"NotAllowedError"DOMExceptionを投げる。注: この制約は§ 6.4 オリジンの混同で挙げられた懸念への対応です。
-
もし options["
password"] がtrueでないなら、空集合を返す。 -
以下のフィルタに一致する認証情報ストアからの資格情報取得 の結果を返す:
-
資格情報が
PasswordCredentialであること -
資格情報の
[[origin]]が origin と同一オリジンであること
-
3.3.2. PasswordCredentialの
[[Create]](origin, options, sameOriginWithAncestors)
[[Create]](origin, options, sameOriginWithAncestors)
は、オリジン(origin)と
CredentialCreationOptions
(options)、および呼び出しコンテキストが祖先と同一オリジンかどうか(sameOriginWithAncestors)を示す
ブール値が与えられて呼び出されます。
アルゴリズムはPasswordCredential
が生成できればそれを、できなければ null を返します。CredentialCreationOptions
辞書には必ず password メンバーがあり、これにはHTMLFormElement
または PasswordCredentialData
が入っていなければなりません。
そのメンバーの値からPasswordCredential
を生成できない場合、このアルゴリズムはTypeError
例外を投げます。
-
アサート: options["
password"] が存在し、かつ sameOriginWithAncestors は未使用である。 -
もし options["
password"] がHTMLFormElementなら、 options["password"] と origin を指定して HTMLFormElementからPasswordCredentialを作成する の結果を返す。例外が発生した場合はそのまま再スローする。 -
もし options["
password"] がPasswordCredentialDataなら、 options["password"] を指定して PasswordCredentialDataからPasswordCredentialを作成する の結果を返す。例外が発生した場合は再スローする。
3.3.3.
PasswordCredentialの[[Store]](credential, sameOriginWithAncestors)
[[Store]](credential, sameOriginWithAncestors)
は、
PasswordCredential
(credential) および呼び出しコンテキストが
祖先と同一オリジン
(sameOriginWithAncestors) かどうかを示すブール値で呼び出されます。
アルゴリズムは、credential が 認証情報ストアに永続化された
時点で undefined を返します。
アルゴリズムは sameOriginWithAncestors が true でない場合、
NotAllowedError を返します。
-
sameOriginWithAncestors が
falseの場合、 "NotAllowedError"DOMExceptionをスローし、ユーザーエージェントの 認証情報ストア は変更しません。注: この制約は § 6.4 オリジンの混同 の懸念に対処するためのものです。
-
ユーザーエージェントの 認証情報ストア に、
PasswordCredential(stored) が存在し、 そのid属性が credential のidで、 かつ[[origin]]スロットが credential の[[origin]]と 同一オリジンの場合、次を実施:-
ユーザーが認証情報の更新を許可した場合(ユーザー仲介定義時に説明):
それ以外の場合、ユーザーが認証情報の保存を許可した場合(ユーザー仲介定義時に説明):
-
認証情報ストアに下記プロパティで
PasswordCredentialを保存する:id-
credential の
id name-
credential の
name iconURL-
credential の
iconURL [[origin]]-
credential の
[[origin]] password-
credential の
password
-
3.3.4. HTMLFormElementからPasswordCredentialを作成
HTMLFormElementから
PasswordCredentialを作成するには、HTMLFormElement
(form)とオリジン(origin)を受け取り、以下の手順を実行します。
注: § 3.1.2 サインイン後の確認と§ 3.1.3 パスワード変更が主な利用例です。
-
dataを新しい
PasswordCredentialData辞書とする。 -
dataの
originメンバー値をorigin値に設定する。 -
formDataを
FormDataコンストラクターでformから生成する。 -
elements を、送信可能な要素のうち、form owner が form であるものを 木構造順で並べたリストとする。
-
newPasswordObservedを
falseとする。 -
elementsの各fieldについて以下を実行:
-
fieldが
autocomplete属性を持たない場合は以降をスキップ。 -
nameをfieldの
name属性値とする。 -
formDataの
has()をnameに対して実行し、結果がfalseなら以降をスキップ。 -
fieldの
autocomplete値に1つ以上のautofill詳細トークン(tokens)が含まれている場合:-
tokensの各tokenについて:
-
tokenが以下のいずれか文字列(ASCII大文字小文字無視)と一致する場合は該当手順を実行:
- "
new-password" -
dataの
passwordメンバー値をformDataのget()でname取得結果に設定し、newPasswordObservedをtrueにする。 - "
current-password" -
newPasswordObservedが
falseなら、dataのpasswordメンバー値をformDataのget()でname取得結果に設定。注: newPasswordObservedが
falseか判定することでnew-passwordフィールドがcurrent-passwordより優先されます。 - "
photo" - "
name"- "
nickname" - "
- "
username"
- "
-
-
-
-
cをPasswordCredentialDataからPasswordCredentialを作成(data)の結果とする。例外発生時は再スロー。
-
Assert: cは
PasswordCredentialである。 -
cを返す。
3.3.5. PasswordCredentialDataからPasswordCredentialを作成
PasswordCredentialData
から
PasswordCredential を作成する手順は、
PasswordCredentialData
(data)を受け取り、以下を実行する。
-
c を新しい
PasswordCredentialオブジェクトとする。 -
c の各プロパティを次のように設定:
-
c を返す。
3.3.6. CredentialRequestOptionsによるPasswordCredential一致判定
CredentialRequestOptions
(options)が与えられたとき、次のアルゴリズムは
PasswordCredential
を get()
リクエストの応答として利用可能な場合は "Matches" を、そうでなければ "Does Not Match" を返します。
-
もし options に
passwordメンバーが存在し、その値がtrueであれば "Matches" を返す。 -
"
Does Not Match" を返す。
4. フェデレーテッドクレデンシャル
4.1.
FederatedCredential インターフェース
[Exposed =Window ,SecureContext ]interface :FederatedCredential Credential {constructor (FederatedCredentialInit );data readonly attribute USVString provider ;readonly attribute DOMString ?protocol ; };FederatedCredential includes CredentialUserData ;dictionary {FederatedCredentialRequestOptions sequence <USVString >;providers sequence <DOMString >; };protocols partial dictionary CredentialRequestOptions {FederatedCredentialRequestOptions ; };federated
provider, 型 USVString, 読み取り専用-
この認証情報のフェデレーションIDプロバイダー。正しいフォーマットの詳細は § 4.1.1 プロバイダーの識別 を参照。
protocol, 型 DOMString, 読み取り専用, nullable-
この認証情報のフェデレーションIDプロバイダーのプロトコル(例: "
openidconnect")。 値がnullの場合は、providerからプロトコルが推定される。 [[type]]-
FederatedCredentialインターフェースオブジェクト は "federated" という値を持つ[[type]]という内部スロットを持つ。 [[discovery]]-
FederatedCredentialインターフェースオブジェクト は "credential store" という値を持つ[[discovery]]という内部スロットを持つ。 FederatedCredential(data)-
このコンストラクタは
FederatedCredentialInit(data) を受け取り、以下のステップを実行する:-
r を、
FederatedCredentialInitからFederatedCredentialを作成 の data で実行した結果とする。それが例外を投げた場合、その例外を再スローする。 -
r を返す。
-
FederatedCredential
オブジェクトは
FederatedCredentialInit
辞書を
navigator.credentials.create()
に渡すことで生成できる。
dictionary :FederatedCredentialInit CredentialData {USVString ;name USVString ;iconURL required USVString ;origin required USVString ;provider DOMString ; };protocol partial dictionary CredentialCreationOptions {FederatedCredentialInit ; };federated
FederatedCredential
オブジェクトはオリジンバウンドである。
FederatedCredentialの
インターフェースオブジェクトは、
Credential
の
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
実装を継承し、独自に
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
と
[[Create]](origin, options, sameOriginWithAncestors)
および
[[Store]](credential, sameOriginWithAncestors)
を備える。
注: 将来ユーザーエージェントで認証トークンを自動取得できるようにする場合は、
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
の独自実装を作ることで対応できる。
4.1.1. プロバイダーの識別
すべてのサイトは、特定のフェデレーテッドアイデンティティプロバイダーを参照する際に同じ識別子を使用するべきです。例えば Facebook Login は "Facebook" や "Facebook Login" や "FB" や "FBL" や "Facebook.com" などと呼ばず、誰もが利用できる正規の識別子を持つべきです。識別が一貫していれば、ユーザーエージェントが役立つことが可能になります。
一貫性のため、本書で定義されたAPIに渡されるフェデレーション(例: FederatedCredentialRequestOptions
の
providers
配列や FederatedCredential
の
provider
プロパティ)は、プロバイダーがサインインに使用する origin のASCIIシリアライゼーション で識別されなければなりません。
つまり、Facebookは https://www.facebook.com、Googleは https://accounts.google.com
で表されます。
この origin のシリアライゼーションには、末尾の U+002F SOLIDUS ("/")
は含まれませんが、ユーザーエージェントはそれを黙って受け入れるべきです: https://accounts.google.com/ は明らかに
https://accounts.google.com と同じ意味です。
4.2. アルゴリズム
4.2.1.
FederatedCredential の
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
は、オリジン(origin)、CredentialRequestOptions
(options)、
および呼び出しコンテキストが祖先と同一オリジン
(sameOriginWithAncestors)である場合だけtrueとなるブール値で呼び出されます。
このアルゴリズムは認証情報ストアから
Credential
オブジェクトの集合を返します。一致する Credential
がなければ、返される集合は空です。
-
もし sameOriginWithAncestors が
falseなら、 "NotAllowedError"DOMExceptionを投げる。注: この制約は§ 6.4 オリジンの混同で挙げられた懸念への対応です。
-
もし options["
federated"] がtrueでないなら、空集合を返す。 -
以下のフィルタに一致する認証情報ストアからの資格情報取得 の結果を返す:
4.2.2. FederatedCredential の
[[Create]](origin, options, sameOriginWithAncestors)
[[Create]](origin, options, sameOriginWithAncestors)
は origin(origin)、CredentialCreationOptions
(options)、および呼び出し元コンテキストが 祖先と同一オリジンの場合のみ true
となるブール値(sameOriginWithAncestors)を受け取ります。
このアルゴリズムは FederatedCredential
が作成できればそれを返し、できなければ null を返します。また、例外的な場合は 例外 を投げます:
-
Assert: options["
federated"] 存在すること、および sameOriginWithAncestors は未使用であること。 -
FederatedCredentialInit から FederatedCredential を作成する を options["
federated"] に対して実行した結果を返す。 それが 例外 を投げた場合は、その例外を再スローする。
4.2.3.
FederatedCredential の [[Store]](credential, sameOriginWithAncestors)
[[Store]](credential, sameOriginWithAncestors)
は
FederatedCredential
(credential)、および呼び出し元コンテキストが 祖先と同一オリジン の場合のみ true
となるブール値(sameOriginWithAncestors)を受け取ります。
このアルゴリズムは credential を credential store に保存したら undefined を返します。
もし sameOriginWithAncestors が true でなければ、NotAllowedError を返します。
-
"
NotAllowedError"DOMExceptionを投げ、ユーザーエージェントの credential store を変更しない。 sameOriginWithAncestors がfalseの場合。注記: この制限は § 6.4 オリジン混同 で提起された懸念に対応するためのものです。
-
もしユーザーエージェントの credential store に
FederatedCredentialが存在し、そのid属性が credential のidであり、[[origin]]スロットが credential の[[origin]]とproviderが credential のproviderである場合は、返す。 -
ユーザーがクレデンシャルの保存を許可した場合(ユーザー操作を定義するときに議論)、
FederatedCredentialを credential store に以下のプロパティで保存する:
4.2.4. FederatedCredentialInit から FederatedCredential を作成する
FederatedCredentialInit
から FederatedCredential を作成する ためには、FederatedCredentialInit
(init) を受け取り、次の手順を実行します。
5. ユーザー仲介
APIを通じてウェブに認証情報を公開することは、ユーザープライバシーにさまざまな影響を与える可能性があります。そのため、ユーザーエージェントは、ユーザーが何が起きているのか、また自身の認証情報が誰と共有されるのかを明示的に理解できるように、いくつかの場合においてユーザー関与を必須としなければなりません。
特定のアクションがユーザーの明示的な同意を得て行われた場合、そのアクションを ユーザー仲介(user mediated)と呼びます。同意は、たとえば認証情報選択UIを操作するなど、ユーザーが直接インターフェースを操作することで表明される場合があります。一般的に、ユーザー仲介アクションでは、何らかの UI を提示し、ユーザーに判断を求めることが含まれます。
明示的なユーザー同意なく静かに行われるアクションは「非仲介的」と言います。たとえば、ユーザーが特定のオリジンへの認証情報への持続的なアクセスをブラウザーで許可した場合などは、ユーザーへ決断を促す UI を表示することなく認証情報が提供されることがあります。
ここでは、すべての認証情報タイプに当てはまるいくつかの要件を明記しますが、実際にはユーザーエージェント側の裁量も大きく(ユーザーを支援できる特権的な立場にあるためです)、また認証情報タイプによっては本節よりさらに厳しい独自要件が課されることもあります。
5.1. クレデンシャルの保存と更新
認証情報は機微なデータであり、その保存に関してユーザーが常にコントロールできる状態でなければなりません。不注意な保存が行われた場合、例えば、特定端末のローカルプロファイルが想定外にオンライン上の一意な人格と結び付くなど、望ましくない事態が生じる可能性があります。そのような驚きのリスクを軽減するため:
-
ユーザー仲介(user mediated)なしに 認証情報を保存・更新すべきではありません(SHOULD NOT)。 例えば、ユーザーエージェントは
store()を呼ぶごとに「この認証情報を保存しますか?」とダイアログを表示する対応が考えられます。また、ユーザーエージェントが「常にパスワードを保存する」といった持続的な同意をユーザーに提供する場合には、ユーザーの同意は推定してもよい(MAY)。 ただし、より限定的なスコープ(例:「生成されたパスワードは常に保存」「このサイトのパスワードのみ保存」など)に配慮することが望ましいです。
-
ユーザーエージェントは、認証情報が保存されたことをユーザーに通知すべきです(SHOULD)。 これはアドレスバー付近のアイコンや同様の方法で実装できます。
-
ユーザーエージェントは、ユーザーが手動で保存済み認証情報を削除できるようにする必要があります(MUST)。 例えば設定ページや、上記の通知経由の操作などで提供してもよいでしょう。
5.2. ユーザー仲介の要求
デフォルトでは、すべてのユーザー仲介
は、各オリジンごとに必須です。これは、サイレントアクセス防止フラグが認証情報ストアでtrueに設定されているためです。ユーザーは、あるオリジンに永続的な認証情報アクセス(たとえば「このサイトにサインインしたままにする」オプション)を許可することもできます。この場合、フラグはfalseとなります。この場合、そのサイトには常にサインイン済みとなり、利便性や使いやすさの観点からは望ましいものの、予期せぬ影響もあり得ます(たとえばユーザーエージェントがこのフラグの状態を複数デバイス間で同期する場合など)。
そのような「驚き」のリスクを軽減するため:
-
ユーザーエージェントは、ユーザーが特定のオリジンまたはすべてのオリジンについてユーザー仲介を要求できるようにしなければなりません(MUST)。この機能は、グローバルなトグルスイッチ(すべてのオリジンのサイレントアクセス防止フラグを
falseにオーバーライドする)や、より細かな設定(特定のオリジンや認証情報ごとの設定)などで実現できます。 -
ユーザーエージェントは、オリジンのサイレントアクセス防止フラグを
falseにユーザー仲介なしで設定してはなりません(MUST NOT)。例として、認証情報選択UI (§ 5.3 認証情報選択で説明)が、ユーザーがチェックボックスを切り替えて、 仲介なしで利用可能にマークできるようにしたり、ユーザーエージェントの認証情報マネージャーの初期設定時に既定値を尋ねたりできます。 -
ユーザーエージェントは、認証情報がオリジンへ提供された際にユーザーへ通知しなければなりません(MUST)。例えばアドレスバーや他のわかりやすい場所でアイコンを表示するなど。
-
ユーザーがオリジンの閲覧データ(CookieやlocalStorageなど)を消去した場合、ユーザーエージェントはそのオリジンのサイレントアクセス防止フラグを
trueに設定しなければなりません(MUST)。
5.3. クレデンシャルの選択
ユーザー仲介(user
mediation)が必要なオリジンで
get()
が呼ばれた場合、ユーザーエージェントはユーザーに認証情報を共有する許可を尋ねなければなりません(MUST)。
この際、ユーザーにそのサイトで利用できる認証情報のリストを示し、どれをウェブサイトへ提供するか選ばせたりリクエスト自体を中止できるようにする
認証情報選択UI
の形式で行うのが望ましいです(SHOULD)。
選択UIは、Webサイトが再現できるUIと明確に区別できるように実装されるべきです(SHOULD)。 たとえばユーザーエージェント独自のUIに重ねて表示するなど、偽装できない形が考えられます。
選択UIには、認証情報を要求しているオリジンの表示が必須です(MUST)。
選択UIには、そのオリジンに関連づいた
Credential
オブジェクトをすべて含めるべきです(SHOULD)。
ユーザーエージェントは、こうした選択UIの利便性を高める目的で、本仕様で規定された属性以外の情報を
Credential
オブジェクトごとに内部的に持ってよい(MAY)。例:ファビコン等によりIDプロバイダーを判別しやすくしても良い。ただし、
追加情報はWebに直接公開してはなりません(MUST NOT)。
選択UIの挙動自体はここでは規定されません。 ユーザーエージェントは、ユーザーに認証方式を理解させ、どの認証情報を提示するか案内するためのUI表現の工夫が推奨されています。 インターフェースは次のようになります:
CredentialRequestOptions
(options)、および
認証情報ストア
から得た
Credential
集合(locally discovered credentials)を引数にして
ユーザーに認証情報を選ばせる
実装を持つことができる。
このアルゴリズムは、ユーザーが認証情報を共有しないことを選んだ場合はnullを返し、
特定の認証情報を選んだ場合は
Credential
を、
認証情報のタイプ自体を選んだ場合は
Credential
インターフェースオブジェクト
を返す。

optionsが 事前マッチ可能 でない場合は、明示的な認証情報リストに加えて 関連認証情報インターフェースオブジェクト も選択肢に加えるのが適切な場合もあります。 たとえばWebAuthn認証器に対応したサイトであれば、 「セキュリティキー」などのエントリーが適切なアイコンとともにリストアップされるかもしれません。
また、場合によってはユーザーエージェントが選択UI自体をスキップすることもあります。 例:唯一の 関連認証情報インターフェースオブジェクト 自体がユーザー操作必須である場合は、ユーザーエージェントが直接そのインターフェースだけを返し内部の仲介フローで同意取得に進む場合があります。
6. セキュリティに関する考慮事項
以下の各節は、セキュリティおよびプライバシーに関するガイドラインを示しています。個々のクレデンシャルタイプは、これらのガイドラインより厳格または緩和されたバージョンを適用することがあります。
6.1. クロスドメインでのクレデンシャルアクセス
認証情報は機密性の高い情報であり、ユーザーエージェントはそれをいつウェブサイトと安全に共有してよいか慎重に判断する必要があります。最も安全なのは、その認証情報が保存された正確なオリジンへの共有に限定することです。しかし、それではWebとしては制限が厳しすぎる場合もあります。たとえば
example.com と admin.example.com のように機能をサブドメインで分けているサイトを考えてください。
ユーザーに煩わしさを与えず認証情報の安全も守るため、ユーザーエージェントは以下の対応を行います:
-
オリジン間で、スキームがセキュリティ上ダウングレードとなる場合には認証情報を共有してはならない(MUST NOT)。 つまり、
http://example.com/で保存された認証情報をhttps://example.com/で利用できるようにするのは、 開発者に安全な通信への移行を促す観点で理にかなう場合があるが、逆(https→http)は危険である。 -
パブリックサフィックスリスト [PSL] を利用して、認証情報の有効範囲を判定するために、 その認証情報の 登録可能ドメイン (
[[origin]])とget()を呼び出しているオリジンの登録可能ドメインを比較してもよい(MAY)。 つまり、https://admin.example.com/やhttps://example.com/で保存された認証情報は、https://www.example.com/からget()を呼び出した際にユーザーへ提示してもよく、その逆も同様。 -
get()に対して、 認証情報のオリジンが呼び出し元のオリジンと完全一致しない場合は、 ユーザーメディエーションなしに、 該当の認証情報を提供してはならない(MUST NOT)。 つまり、https://example.com用のCredentialオブジェクトはhttps://www.example.comへ直接は返さないが、 選択ダイアログを通じてはユーザーへ提示できる。
6.2. クレデンシャル漏洩
開発者は、クロスサイトスクリプティング攻撃がユーザーのアカウントへの永続的なアクセスに変わるリスクを軽減するために、データ送信先を制限する適切なContent Security Policy [CSP]を設定するなど、いくつかの対策を講じることが強く推奨されます。特に、開発者は次のディレクティブがページのポリシーに明示的または暗黙的に設定されていることを確認すべきです:
-
script-src および object-src は、どちらもページ上でのスクリプト実行を制限し、クロスサイトスクリプティング攻撃がそもそも成功しにくくなります。もしサイトが
form要素を利用している場合は、form-action ディレクティブも設定すべきです。 -
connect-src は、
fetch()がデータを送信できるオリジンを制限します(これにより、資格情報がevil.comなどに流出するリスクを低減します)。 -
child-src は、ページ内に埋め込むことができるネストされた閲覧コンテキストを制限し、悪意のある
postMessage()ターゲットの注入をより困難にします。[HTML]
もちろん、開発者は入力と出力の適切なエスケープ処理や、Subresource Integrity [SRI]など、他の防御策も検討すべきです。
特定のクレデンシャルタイプを定義する際には、クレデンシャルデータの送信方法にも十分な配慮を行うべきです。例えば、同一オリジンのエンドポイントのみ送信を許可する伝送方式を定義するのが妥当かもしれません。
6.3. 安全でないサイト
ユーザーエージェントは、ここで定義されているAPIをセキュアコンテキストではない環境に公開してはなりません(MUST NOT)。ユーザーエージェントは、ユーザーの資格情報を保存し、サインインフォームに自動入力するオートフィル機能を非・信頼できるURL上で実装する場合がありますが、そうしたサイトは資格情報マネージャと直接やり取りすることは信頼できず、また、それらのサイトがセキュアコンテキストで保存された資格情報へアクセスすることはできません(MUST NOT)。
6.4. オリジン混同
フレーム化されたページが現行標準で定義されたAPIにアクセスできる場合、ユーザーがトップレベル閲覧コンテキスト以外のオリジンに対してクレデンシャルへのアクセス権を誤って与えてしまう可能性があります。トップレベル閲覧コンテキストこそが、ユーザーが理解できる唯一のセキュリティオリジンです。
本書では、ユーザーエージェントがUI設計に十分配慮すれば、いくつかのクレデンシャルタイプはそうしたコンテキストにも安全に公開可能と考え、Credential Management APIをそれらのコンテキストにも公開しています。
しかしながら、特定のクレデンシャルタイプはリスクなしでこうしたコンテキストに公開するのが困難です。これらのタイプは、[[Create]](origin, options, sameOriginWithAncestors)、
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)、
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)、
[[Store]](credential, sameOriginWithAncestors)
の各メソッドにおいて適切に制限されています。
例えば、PasswordCredentialの
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
メソッドは、Workerや非トップレベル閲覧コンテキストから呼ばれた場合、即座に空集合を返します。
6.5. サインアウト
ユーザーが§5.2
ユーザー仲介の要求で述べたように、ウェブサイトへの自動サインインを選択している場合、ユーザーエージェントは要求に応じてオリジンにクレデンシャルを提供します。ウェブサイトは、CredentialsContainerの
preventSilentAccess()
メソッドを呼び出すことで、この動作を抑制できます。これにより特定のオリジンで自動サインインを停止できます。
ユーザーエージェントはウェブサイトが適切に振る舞うことに依存しています。不注意または悪意のあるウェブサイトがこのメソッドを呼ばなければ、ユーザーエージェントはユーザーの意図に反してクレデンシャルを提供し続けることになります。これは、サイトがユーザーが「サインアウト」をクリックしてもクレデンシャルを消去しない現状よりも若干悪化します。なぜなら、ユーザーエージェントが認証に加担することになるからです。
ユーザーはこの動作を制御できなければなりません。§5.2
ユーザー仲介の要求で述べた通り、オリジンのCookieを消去すると、そのオリジンのサイレントアクセス防止フラグも
クレデンシャルストア内でtrueにリセットされます。加えて、ユーザーエージェントは特定オリジンの自動サインインを無効化できるUI(例えばクレデンシャルが提供された通知に連動したUIなど)も提供すべきです。
7. プライバシーに関する考慮事項
7.1. タイミング攻撃
ユーザーがあるオリジンに対してクレデンシャルを持っていない場合、get()
の呼び出しは非常に素早く解決されます。悪意のあるウェブサイトは、クレデンシャルを持っていないユーザーと、クレデンシャルは持っているが共有しないユーザーとを区別することができます。
ユーザーエージェントはクレデンシャル要求にレート制限を設けるべきです。短時間に何度もクレデンシャルを要求するページはほぼ確実に悪質です。
7.2. 選択UIの漏洩
ユーザーエージェントの認証情報選択UIがオリジン提供の画像(例えば
Credential
がサイトのファビコンを表示する場合など)を表示する場合、
これら画像のリクエストは、選択UIの表示と直接結び付けてはなりません(MUST NOT)。選択UIの利用が外部に漏れることを防ぐためです。一つの方法は、Credential
を保存または更新する時に画像をバックグラウンドで取得し、
Credential
の存続期間中キャッシュする方法です。
これらの画像はcredentials modeを"omit"、
service-workers modeを"none"、
clientをnull、
initiatorを空文字列、
destination を"subresource"
に設定して取得しなければなりません(MUST)。
さらに、ユーザーエージェントがユーザーに認証情報に紐付いた名前やアイコンの変更を許可する場合、 そのデータの変更はウェブサイトには公開すべきではありません(SHOULD NOT)。 例えば、一つのオリジン用に「偽物アカウント」「本物アカウント」とユーザーが名付けた場合などを考えてください。
7.3. ローカル保存データ
このAPIは、オリジンに対し、ユーザープロファイルとともにデータを永続的に保存する機能を提供します。 多くのユーザーエージェントはクレデンシャルデータを「閲覧データ」(Cookieなど)とは区別して扱うため、ユーザーがCookieを消去してオリジンの痕跡がすべて消えたと思っても、クレデンシャルが残っていて驚く可能性があります。
ユーザーエージェントは、オリジンごとにクレデンシャルデータが保存されていることをユーザーに明示するUIを提供し、不要になったデータを容易に削除できるようにすべきです。
8. 実装に関する考慮事項
この節は規範的ではありません。
8.1. ウェブサイト制作者向け
ここにAPIをいつ・どのように使うべきか、特にmediation
に関する指針などを追記すること。
[w3c/webappsec Issue #290]
fetch() で FormData
ボディを送信する際の認証情報エンコーディング制限を記述すること。
特定の認証情報タイプの機能検出を行う場合、開発者は
関連する Credential
の特化オブジェクトが存在するかを確認することを推奨します。
navigator.credentals の有無チェックだけでは、
API自体が存在することしか分からず、
必要な種別の認証情報がサポートされているかどうかまでは分かりません。
例えばパスワードを必要とするサイトでは、
if (window.PasswordCredential) チェックが
サポート有無を確認する上で最も効果的です。
8.2. 拡張ポイント
この文書は、さまざまな認証要件に対応するタイプの認証情報を拡張で追加できる、汎用的かつ高レベルなAPIを提供します。そのための手順は、おそらく直感的です:
-
Credentialを継承する新しいインターフェイスを定義します: -
[[Create]](origin, options, sameOriginWithAncestors)、[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)、[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)、[[Store]](credential, sameOriginWithAncestors)をExampleCredentialの インターフェースオブジェクトに定義します。[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)は永続的に 有効な 認証情報に適しており、 単に認証情報ストアから コピーしてくるだけで済みます。 一方、[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)は 認証情報ソースから 再生成が必要な 認証情報に適しています。PublicKeyCredentialの[[Create]](origin, options, sameOriginWithAncestors)や[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)のような 長時間かかる操作については、options.signalを使って開発者が中断できるようにすることが推奨されます。 詳細は DOM § 3.3 APIでAbortControllerやAbortSignalオブジェクトを利用する を参照してください。ExampleCredentialの[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)内部メソッドは origin(origin)、CredentialRequestOptionsオブジェクト(options)、呼び出しコンテキストが祖先と同一オリジンの場合のみtrueとなるブール値を受け取ります。 アルゴリズムは与えられたオプションに合致するCredentialオブジェクトの集合を返し、一致するオブジェクトがなければ空集合を返します。-
アサーション:
options[example] が存在していること。 -
もし
options[example] が truthy でなければ空集合を返します。 -
認証情報ストア内の各 credential について:
-
・・・
-
-
-
ExampleCredentialインターフェースオブジェクト の[[type]]スロットの値を定義します: -
ExampleCredentialインターフェースオブジェクト の[[discovery]]スロットの値を定義します: -
新しい認証情報タイプが
CredentialRequestOptionsに必要なオプションを拡張し、get()で適切に応答できるようにします: -
CredentialCreationOptionsも同様に拡張し、Credentialオブジェクトをcreate()で作成できるようにします: -
新しい認証情報タイプが
conditionalユーザーメディエーションに対応する場合、ExampleCredential/isConditionalMediationAvailable()を定義し、a promise resolved withtrueを返します。 -
§ 2.1.2.1 登録エントリ要件および更新手順に従い、 新しい「example」認証情報タイプと その対応をCredential Type Registryに追加します:
-
CredentialCreationOptionsとCredentialRequestOptionsの オプションメンバー識別子 (この例では"example") -
適切なインターフェースオブジェクトの 識別子(この例では
ExampleCredential)
注記: 認証情報タイプのオプション辞書の オプションメンバー識別子 は、
CredentialCreationOptionsおよびCredentialRequestOptionsの両方で同一である必要があり、 credential type値とCredentialインターフェースオブジェクトの[[type]]スロット値とも一致すべきです。 -
こうした拡張にあたり、たとえば複数のCredential
を返したい場合や、複雑な多要素認証フローの実装など、新しいプリミティブが必要になる場合もあります。
そのような場合は
CredentialsContainer
に getAll() のようなメソッドを追加し、sequence<Credential>
を返す設計や、異なるタイプの認証情報取得フローのための合理的な仕組みの定義も考えられます。
このような拡張を検討する際は、 public-webappsec@ へ相談・レビューを依頼することを推奨します。
8.3. ブラウザー拡張
理想的には、拡張機能システムを実装するユーザーエージェントは、第三者がこれらAPIエンドポイントにフックして、サードパーティのクレデンシャル管理ソフトの動作をユーザーエージェント自身と同じ形で改善できるようにするべきです。
これは、ユーザーエージェントが仲介する複雑な新APIを用意する場合から、拡張機能が自分自身の目的でget()やstore()のエンドポイントを上書きできるようにする場合まで、幅広く考えられます。
9. 今後の課題
この節は規範的ではありません。
ここで定義されたAPIは、ユーザーエージェントの資格情報マネージャをウェブに公開するための最低限の機能のみを提供し、ウェブがこれらの資格情報マネージャにフェデレーションIDプロバイダの利用状況を理解させることを可能にします。次の論理的なステップは、[WEB-LOGIN]のような文書(および、ある程度はMozillaのBrowserID [BROWSERID])で示された方向性に沿ったものになるでしょう。
ユーザーエージェントは、ユーザー・アイデンティティプロバイダー・ウェブサイト間の関係を効果的に仲介できる唯一の立場にあります。ユーザーエージェントが一般的な認証フローに伴うリスクや混乱を軽減できれば、ユーザーは現在よりもはるかに良い状況になるでしょう。
この情報を公開する自然な方法としては、FederatedCredential
インターフェースを認証トークンなどのプロパティで拡張したり、プロバイダーがサポートする認証タイプを宣言するプロパティを持つマニフェスト形式を追加することが考えられます。
ここで説明したAPIは、ユーザー操作を必要とするユースケースや、クレデンシャルを要求したウェブサイト以外のサイトとのやり取りを含むユースケースにも対応できるよう十分に拡張可能となるよう設計されています。Promiseベースのシステムは、複数の閲覧コンテキスト間(例:idp.com
での仲介活動によって rp.com にPromiseが返される場合)や、将来デバイス・ユーザーエージェント間(例:[WEBAUTHN])での非同期フローをAPI自体の再設計なしにサポートできる拡張性を持つことを期待しています。
少しずつ前進していきます。