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(すなわち「オプション辞書」)で仕様ごとに使われます。
注: このレジストリは関連する認証情報インターフェースオブジェクトアルゴリズムで利用されます。
| 認証情報タイプ (アルファベット順) | オプションメンバー識別子 | 適切なインターフェースオブジェクト | 取得パーミッションポリシー | 作成パーミッションポリシー | 仕様 | 申請者連絡先 |
|---|---|---|---|---|---|---|
| digital-credential | digital | DigitalCredential
| digital-credentials-get | null | [DIGITAL-CREDENTIALS] | WICG |
| federated | federated | FederatedCredential
| null | null | 本仕様:§ 4 フェデレーテッド認証情報 | W3C |
| identity | identity | IdentityCredential
| identity-credentials-get | null | [FEDCM] | W3C |
| otp | otp | OTPCredential
| otp-credentials | null | [WEB-OTP] | WICG |
| password | password | PasswordCredential
| null | null | 本仕様:§ 3 パスワード認証情報 | W3C |
| public-key | publicKey | PublicKeyCredential
| publickey-credentials-get | publickey-credentials-create | [WEBAUTHN] | W3C |
2.1.2.1. 登録エントリ要件および更新プロセス
-
各レジストリエントリは、認証情報仕様の
CredentialCreationOptionsおよびCredentialRequestOptionsで拡張される辞書メンバーの識別子(レジストリではオプションメンバー識別子と呼ばれる)を明記しなければなりません。 -
各レジストリエントリは、適切なインターフェースオブジェクトの識別子を明記しなければなりません。
-
各レジストリエントリは、取得パーミッションポリシーのパーミッション(認証情報の要求実行時に使用)か、パーミッションポリシーが指定されていなければnullを明記しなければなりません。
-
各レジストリエントリは、作成パーミッションポリシーのパーミッション(認証情報の作成実行時に使用)か、パーミッションポリシーが指定されていなければnullを明記しなければなりません。
-
各レジストリエントリの仕様には申請者の連絡先情報を含めなければなりません。
このレジストリの更新は、認証情報タイプのレジストリエントリの追加・変更・削除です。誰でもwebappsec-credential-managementリポジトリへのプルリクエストで更新を申請できます。 Webアプリケーションセキュリティ作業部会が次回会議の議題に載せ申請者に通知します。 審議と決定はW3C Webアプリケーションセキュリティ作業部会の合意によります。 議長が申請者に結果を通知し、レジストリを更新します。
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()が呼ばれると、ユーザーエージェントは Request aCredentialをoptionsに対して実行した結果を返さなければなりません。CredentialsContainer.get(options) メソッドの引数。 パラメーター 型 Nullable Optional 説明 optionsCredentialRequestOptions✘ ✔ リクエストのスコープを制御するためのプロパティセット。 store(credential)-
store()が呼ばれると、ユーザーエージェントは Store aCredentialをcredentialに対して実行した結果を返さなければなりません。CredentialsContainer.store(credential) メソッドの引数。 パラメーター 型 Nullable Optional 説明 credentialCredential✘ ✘ 保存する認証情報。 create(options)-
create()が呼ばれると、ユーザーエージェントは Create aCredentialをoptionsに対して実行した結果を返さなければなりません。CredentialsContainer.create(options) メソッドの引数。 パラメーター 型 Nullable Optional 説明 optionsCredentialCreationOptions✘ ✔ Credentialの作成に使われるオプション。 preventSilentAccess()-
preventSilentAccess()が呼ばれると、ユーザーエージェントは Prevent Silent Access を現在の設定オブジェクトに対して実行した結果を返さなければなりません。注: ここで意図されているのは、オリジン側からの「サインアウトした」ことを示すシグナルです。 つまり、「サインアウト」ボタンをクリックした後、サイトはユーザーのセッション情報を更新し、
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 認証情報のリクエストで定義されています。 uiMode、型は DOMString-
このプロパティは、認証情報リクエスト時にユーザーエージェントがユーザー仲介を実施する場合のUIモードを指定します。各値の意味は
CredentialUiModeで説明されています。処理詳細は§ 2.5.1 認証情報のリクエストで定義されています。 signal、型は AbortSignal-
このプロパティにより、開発者は進行中の
get()操作を中断できます。 中断された操作は通常通り完了(多くの場合は操作終了後に中断が発生)するか、abort reason で reject されます。
unmediated メンバーが定義されていました。これを true にすると
mediation
が
"silent"
となったのと同じ効果でした。
false だと
mediation
が "optional"
となったのと同じ効果でした。
unmediated は非推奨とみなされるべきです。新しいコードでは代わりに
mediation
を使ってください。
CredentialCreationOptions
または CredentialRequestOptions
(options) に対応する
関連資格情報インターフェースオブジェクト
の集合は、次の手順で集めます:
注: このアルゴリズムは資格情報タイプレジストリを利用します。
-
settings を 現在の設定オブジェクトとする。
-
options の各 optionKey → optionValue について:
-
credentialInterfaceObject を、settings のグローバルオブジェクト上で、 該当インターフェースオブジェクトで、 オプションメンバー識別子が optionKey のものとする。
-
アサート: credentialInterfaceObject の
[[type]]スロットの値が、資格情報タイプ のうち オプションメンバー識別子 が optionKey となるものと一致する。 -
credentialInterfaceObject を relevant interface objects に追加する。
-
-
relevant interface objects を返す。
CredentialRequestOptions
(options) が
事前マッチ可能(a priori matchable) となるのは、次の手順で
true を返す場合です:
-
options の 関連資格情報インターフェースオブジェクト の各 interface について:
-
もし interface の
[[discovery]]スロット値が "credential store" でなければfalseを返す。
-
-
trueを返す。
注:
get(options)
実行時、ユーザー仲介なしに返す認証情報は、
渡された CredentialRequestOptions
が
事前マッチ可能 な場合のみとなります。
もし外部サービスからの発見を要するような認証情報タイプ(OAuthトークン、セキュリティキー認証器など)がリクエストされた場合は、
ユーザー仲介して、その発見を(フェデレーテッドアイデンティティプロバイダーやBTLEデバイスの選択等で)誘導する必要があります。
2.3.2. メディエーション要件
get(options)
または create(options)
によってリクエストを行う際、開発者は適切な CredentialMediationRequirement
列挙値を選ぶことで、ケースごとのユーザー仲介要件を設定できます。
注: § 5 ユーザー仲介の節では、この概念全般の詳細と、ユーザーエージェントが特定オリジンに対する個々のリクエストをどのように扱うかへの影響について、より詳しく説明します。)
enum {CredentialMediationRequirement "silent" ,"optional" ,"conditional" ,"required" };
silent-
指定された操作について、ユーザー仲介は抑止されます。ユーザーの関与なしで操作を実行できるならそれで良し。ユーザーの関与が必要な場合は、ユーザーを巻き込むのではなく、操作は
nullを返します。注: 想定される用途は、 「このサイトにサインインしたままにする」シナリオを支援することです。つまり、ユーザーが自動的にサインインされるべき場合は資格情報を黙って取得したいが、 ユーザーが能動的にサインインを選ぶまでは、サインインプロンプトで煩わせるのを遅らせたい、というケースです。
optional-
指定された操作についてユーザー仲介なしで資格情報を渡せる場合は、そのようにします。ユーザー仲介が要求される場合、ユーザーエージェントは判断にユーザーを関与させます。
注: これは
get()のデフォルト動作であり、開発者が「ユーザーはサインイン操作を開始するつもりだ」と合理的に確信できるケースを意図しています。例えばユーザーが直前に「sign-in」をクリックした場合などは、 必要であれば認証情報選択UIが出ても、驚いたり混乱したりしないでしょう。 conditional-
get()では、発見された資格情報が、資格情報を要求しているオリジンの表示とともに、非モーダルダイアログでユーザーに提示されます。ユーザーがダイアログ外でジェスチャーを行うと、そのダイアログは、Promiseを解決もrejectもせずに、またユーザー可視のエラー状態を引き起こすこともなく、閉じます。ユーザーが資格情報を選択するジェスチャーを行った場合、その資格情報は呼び出し元に返されます。サイレントアクセス防止フラグは、実際の値に関わらずtrueとして扱われます。すなわち、適用可能な資格情報が発見された場合、conditionalの挙動は常に、何らかの形でユーザー仲介を伴います。資格情報が発見されない場合、ユーザーエージェントは、資格情報タイプに依存する方法でユーザーにアクションを促してもよい(例:資格情報を含むデバイスを挿入する等)。いずれにせよ、
get()メソッドは、適用可能な資格情報がないことをWebサイトに漏らさないため、直ちにnullで解決してはなりません。Webサイトが
conditionalをget()メソッドに渡せるのは、それが参照するすべての資格情報インターフェースがisConditionalMediationAvailable()をオーバーライドして、Promiseがtrueで解決するようにしている場合に限られます。create()については、ユーザーが以前に認証情報の作成へ同意していて、かつユーザーエージェントが直近で認証を仲介したことを把握している場合、create()呼び出しは、追加の目立つモーダル操作なしに解決されることがあります。ユーザーエージェントが直近で認証を仲介していない、または認証情報作成の同意を持っていない場合、呼び出しは "NotAllowedError"DOMExceptionをスローしなければなりません。 required-
ユーザーエージェントは、オリジンに対してサイレントアクセス防止フラグが未設定であっても、ユーザー仲介なしに資格情報を渡しません。
注: この要件は、再認証 または ユーザー切り替えシナリオを支援することを意図しています。さらに、この要件は特定の操作に紐付いており、オリジンに対するサイレントアクセス防止フラグには影響しません。そのフラグを設定するには、開発者は
preventSilentAccess()を呼び出してください。
2.3.3. UIモード
get(options)
によってリクエストを行う際、開発者は適切な CredentialUiMode
列挙値を選ぶことで、望ましいユーザー仲介モードを示すことができます。
UIモード欄にはデフォルト値がありません。指定されない場合、[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
メソッドは、ユーザーエージェントの挙動を指定するために
CredentialMediationRequirement
のみを考慮しなければなりません。
注: これにより呼び出し元は、ユーザー仲介が発生する場合に、利用可能な異なる形態のユーザー仲介を区別できます。
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
ユーザー仲介の要求で説明)についてはサインインされ、そうした挙動にオプトインしていないユーザーは、文脈なしに混乱を招く認証情報選択UIが突然表示されることで煩わされません:
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"
に設定して渡すことで、ユーザーエージェントに仲介を要求させられます:
注: ブラウザーまたは資格情報タイプのセキュリティモデルによっては、 資格情報がWebサイトへ渡される前に、マスターパスワードの入力、指紋スキャンなど、何らかの方法でユーザー自身に認証を求める必要があるかもしれません。
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"
に設定して渡すことで、「Add account」ボタンのクリックに対して資格情報が自動的に返されないようにできます:
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が完全にアクティブでなければ、"
InvalidStateError"DOMExceptionでrejectされるプロミスを返す。 -
もし
options.が中断済みなら、その abort reasonでrejectされるプロミスを返す。signal -
interfaces を、options の 関連資格情報インターフェースオブジェクトとする。
-
もしinterfacesが 空 なら、"
NotSupportedError"DOMExceptionでrejectされるプロミスを返す。 -
各 interface について:
-
もし options.
mediationがconditionalかつ interface がconditionalのユーザー仲介 をサポートしないなら、"TypeError"DOMExceptionでrejectされるプロミスを返す。 -
もし options.
uiModeがimmediateかつ interface がimmediateのユーザー仲介 をサポートしないなら、"TypeError"DOMExceptionでrejectされるプロミスを返す。 -
もし settings の アクティブ資格情報タイプ が interface の
[[type]]を含んでいる場合、"NotAllowedError"DOMExceptionでrejectされるプロミスを返す。 -
set append操作でinterfaceの
[[type]]をsettingsのアクティブ資格情報タイプに追加する。
-
-
origin を settings の オリジンとする。
-
sameOriginWithAncestors を、settings が祖先と同一オリジンの場合は
true、そうでなければfalseとする。 -
options の関連資格情報インターフェースオブジェクトごとに:
-
permission を interface の
[[type]]のGet Permissions Policyとする。 -
permission が null なら継続。
-
document が 未使用許可されていない permission なら、"
NotAllowedError"DOMExceptionでrejectされるプロミスを返す。
-
-
p を 新しいプロミスとする。
-
次の手順を並列で実行:
-
credentials を、認証ストアから資格情報を収集した結果(origin、options、sameOriginWithAncestorsを渡す)とする。
-
以下すべてが真なら、p を credentials[0] で解決し、残りをスキップ:
-
credentials の 要素数が 1 である
-
origin が ユーザー仲介を要求していない
-
options が 事前マッチ可能 である。
-
options.
mediationが "conditional" でない。
モデルとして正しいか未検討。パスワード認証もしくはwebauthn型の資格情報を受け入れたいサイトで、前者の利用者がサインインを維持したい場合に、 強制的な選択ダイアログなしで対応できると便利。
-
-
もしoptionsの
mediationが "silent" であれば、 resolve p にnullを指定し、以降の手順をスキップ。 -
result を ユーザーに資格情報の選択を促す操作(optionsと credentialsを渡す)の結果とする。
-
もしresultがインターフェースオブジェクトであれば:
-
resultをresultの
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)実行結果(origin、options、sameOriginWithAncestorsを渡す)に置き換える。それが例外を投げた場合:
-
投げられた例外をeとする。
-
タスクキューへglobalのDOM操作タスクソース で下記サブステップを実行:
-
reject p に e を指定。
-
-
これらサブステップを終了。
-
-
-
アサート: result は
nullまたはCredentialのはずである。 -
もし result が
Credentialなら、resolve p に result を指定。 -
もし result が
nullかつ、options.mediationがconditionalでないなら、resolve p に result を指定。注: options.
mediationがconditionalで資格情報nullが発見された場合、プロミスpはresolveされません。
-
-
-
各 interface について:
-
remove 操作で 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 が 完全にアクティブでなければ、 "
InvalidStateError"DOMExceptionで rejectされるプロミスを返す。 -
現在の設定オブジェクトが 祖先と同一オリジンであれば sameOriginWithAncestors を
true、そうでなければfalseとする。 -
p を 新しいプロミス とする。
-
もし settings の アクティブ資格情報タイプ が credential の
[[type]]を 含んでいる場合、 "NotAllowedError"DOMExceptionで rejectされるプロミスを返す。 -
set append 操作で、credential の
[[type]]を settings の アクティブ資格情報タイプ に追加する。 -
以下の手順を 並列で実行:
-
credential の インターフェースオブジェクトの
[[Store]](credential, sameOriginWithAncestors)内部メソッドを credential および sameOriginWithAncestors で実行する。それが例外を投げた場合:
-
スローされた 例外 を e とする。
-
タスクキュー で global の DOM操作タスクソース に基づき、次のサブステップを実行:
-
reject p に e を指定する。
-
そうでなければ resolve p に
undefinedを指定する。 -
-
-
-
remove 操作で 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が完全にアクティブでなければ、 "
InvalidStateError"DOMExceptionでrejectされるプロミスを返す。 -
現在の設定オブジェクトが 祖先と同一オリジンの場合は sameOriginWithAncestors を
true、そうでなければfalseにする。 -
interfacesをoptionsの集合である 関連資格情報インターフェースオブジェクト とする。
-
下記いずれかが成り立てば、
NotSupportedErrorでrejectされたプロミスを返す:-
globalが関連付けられた Document を持たない。
-
interfacesの要素数が1より大きい。
注: 将来的にこの制約を緩和して、ユーザーエージェントが複数の資格情報タイプからユーザーに選ばせ「サインアップ」用途を支援することもありえる。現時点では辞書は単一項目に制限されている。
-
-
interfacesの各interfaceについて:
-
permission をinterfaceの
[[type]]のCreate Permissions Policyとする。 -
permissionがnullなら続行。
-
もしdocumentが未allowed to use permissionならば、 "
NotAllowedError"DOMExceptionでrejectされたプロミスを返す。
-
-
options.が中断済みであれば、その abort reasonでrejectされたプロミスを返す。signal -
type を interfaces[0] の
[[type]]とする。 -
もしsettingsのアクティブ資格情報タイプがtypeを含んでいれば、 "
NotAllowedError"DOMExceptionでrejectされたプロミスを返す。 -
set append操作でtypeをsettingsの アクティブ資格情報タイプに追加する。
-
origin を settings のオリジンとする。
-
p を新しいプロミスとする。
-
次の手順を並列で実行:
-
r をinterfaces[0] の
[[Create]](origin, options, sameOriginWithAncestors)内部メソッドをorigin、options、sameOriginWithAncestorsで実行した結果とする。それが例外を投げた場合:
-
スローされた例外をeとする。
-
タスクキューでglobalのDOM操作タスクソース上で 次のサブステップを実行:
-
reject p に e を指定。
-
-
これらサブステップを終了。
-
-
もしrが
Credentialまたはnullであれば、resolve p に r を渡して手順終了。 -
アサート: r は(§2.2.1.4 [[Create]]内部メソッド定義の)アルゴリズムである。
-
タスクキューでglobalのDOM操作タスクソース上で以下のサブステップを実行:
-
-
-
remove操作でtypeをsettingsの アクティブ資格情報タイプから除外。
-
-
p を返す。
2.5.5. サイレントアクセスの防止
サイレントアクセス防止アルゴリズムは、
環境設定オブジェクト(settings)を受け取り、
Promise
を返します。このプロミスはサイレントアクセス防止フラグが
認証情報ストアに永続化された時点で解決されます。
-
originをsettingsのオリジンとする。
-
もしsettingsの関連グローバルオブジェクトの 関連付けられた Documentが 完全にアクティブでなければ、 "
InvalidStateError"DOMExceptionでrejectされるプロミスを返す。 -
pを新しいプロミスとする。
-
以下の手順を並列で実行:
-
originのサイレントアクセス防止フラグを 認証情報ストアでセットする。
-
resolve 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 { // ここで基本的なログインフォームへフォールバックするコードを書く。 } }); } });
あるいはウェブサイトは、認証情報データを単に
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()
を必ず呼ぶのが難しくなります。
注: ユーザーエージェントが表示する認証情報選択UIでは、
現オリジン用に保存されていない認証情報もユーザーが選べる場合があります。
例えば 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/で利用可能にすることは、 開発者に安全な通信への移行を促す観点で許容されますが、その逆は危険です。 -
ユーザーエージェントは認証情報の実質的なスコープを決定するためにPublic Suffix List [PSL]を使ってもよい(MAY)。 すなわち認証情報の
[[origin]]の登録可能ドメインと、get()を呼び出したオリジンで比較できます。 たとえばhttps://admin.example.com/やhttps://example.com/で保存した認証情報は、https://www.example.com/からget()を呼び出した際にもユーザーに提示でき、逆も可能です。 -
認証情報のオリジンが呼び出し元のオリジンと正確に一致しない場合、 ユーザー仲介 なしでその認証情報を
get()応答として返してはなりません(MUST NOT)。 つまり、https://example.comのCredentialが直接https://www.example.comへ返されることはありませんが、 認証情報選択UI経由でユーザーに提示することは可能です。
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を継承する新しいインターフェースを定義します: -
ExampleCredentialの インターフェースオブジェクト上に、適切な[[Create]](origin, options, sameOriginWithAncestors)、[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)、[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)、[[Store]](credential, sameOriginWithAncestors)メソッドを定義してください。[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)は、常に有効である認証情報に適しており、そのため単純に認証情報ストアからコピーできます。一方で、[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)は、認証情報ソースから再生成が必要な認証情報に適しています。たとえば
PublicKeyCredentialの[[Create]](origin, options, sameOriginWithAncestors)や[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)のような長時間処理はoptions.signalを利用して abort 処理ができるのが望ましいです。 詳細な方法については DOM § 3.3 AbortController/AbortSignal のAPI統合方法 をご覧ください。ExampleCredentialの[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)内部メソッドは、オリジン(origin)、CredentialRequestOptionsオブジェクト(options)、呼び出しコンテキストが祖先と同一オリジンかを示すブール値を受け取ります。 アルゴリズムは与えられた options に一致するCredential群を返します。一致がなければ返値は空集合になります。-
Assert:
options[example] exists. -
If
options[example] is not truthy, return the empty set. -
For each credential in the 認証情報ストアについて:
-
...
-
-
-
ExampleCredentialの インターフェースオブジェクトの[[type]]スロット値を定義します: -
ExampleCredentialの インターフェースオブジェクトの[[discovery]]スロット値も定義してください: -
新しい認証情報タイプが
get()を適切に処理できるよう、 必要な option をCredentialRequestOptionsに追加してください: -
新しい認証情報タイプで
create()を受けてCredentialオブジェクトを作成できるよう、必要なデータをCredentialCreationOptionsに追加してください: -
新しい認証情報タイプが
conditionalなユーザー仲介を サポートする場合は、ExampleCredential/isConditionalMediationAvailable()が a promise resolved withtrueを返すようにしてください。 -
§ 2.1.2.1 登録エントリ要件と更新手順の手順に従い、 新しい"example" 認証情報タイプについて Credential Type Registry に次を追加してください:
-
該当
CredentialCreationOptionsおよびCredentialRequestOptionsの Options Member Identifier (この例では "example") -
対応するインターフェースオブジェクト 識別子 (この例では
ExampleCredential)
注: 認証情報タイプ の option 辞書の Options Member Identifier は必ず
CredentialCreationOptionsとCredentialRequestOptionsで共通のものとしてください。 これは 認証情報タイプ値(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自体の再設計なしにサポートできる拡張性を持つことを期待しています。
少しずつ前進していきます。