Chrome 120 では、FedCM 用にログイン ステータス API が提供されています。 Login Status API(旧称 IdP Sign-in Status API)を使用すると、ウェブサイト(特に ID プロバイダ)はユーザーがログインまたはログアウトしているときにブラウザにシグナルを送信できます。このシグナルは、サイレント タイミング攻撃の問題に対処するために FedCM によって使用されます。これにより、FedCM はサードパーティ Cookie なしで動作できるようになります。今回のアップデートでは、作業範囲の一部として、FedCM の出荷に関する最初の意図で以前に特定された、下位互換性のない残りの変更に対処しています。
Login Status API はプライバシーのプロパティとユーザビリティを向上させますが、リリース後は下位互換性のない変更となります。FedCM の既存の実装がある場合は、次の手順でアップデートしてください。
さらに、Chrome には 2 つの新しいフェデレーション認証情報管理(FedCM)機能が搭載されています。
- Error API: ログイン試行が失敗した場合、ID アサーション エンドポイントからのサーバー応答に基づいてネイティブ UI でユーザーに通知します(存在する場合)。
- Auto-Selected Flag API: フローで認証情報が自動的に選択された場合に、ID プロバイダ(IdP)と証明書利用者(RP)に通知します。
Login Status API
Login Status API は、ウェブサイト(特に IdP)が IdP でのユーザーのログイン ステータスをブラウザに伝えるメカニズムです。この API を使用すると、ブラウザは IdP への不要なリクエストを減らし、潜在的なタイミング攻撃を軽減できます。
ユーザーのログイン ステータスをブラウザに伝える
ユーザーが IdP にログインしたとき、またはユーザーがすべての IdP アカウントからログアウトしたときに、IdP は HTTP ヘッダーを送信するか、JavaScript API を呼び出して、ユーザーのログイン ステータスをブラウザに通知できます。IdP(構成 URL で識別される)ごとに、ブラウザはログイン状態を表す 3 状態変数を保持し、値は logged-in
、logged-out
、unknown
になります。デフォルトの状態は unknown
です。
ユーザーがログインしていることを示すには、トップレベル ナビゲーションまたは同一オリジン サブリソース リクエストで Set-Login: logged-in
HTTP ヘッダーを送信します。
Set-Login: logged-in
または、IdP オリジンから JavaScript API navigator.login.setStatus('logged-in')
を呼び出します。
navigator.login.setStatus('logged-in');
これらの呼び出しは、ユーザーのログイン ステータスを logged-in
として記録します。ユーザーのログイン ステータスが logged-in
に設定されている場合、FedCM を呼び出している RP が IdP のアカウント リスト エンドポイントにリクエストを行い、利用可能なアカウントを FedCM ダイアログに表示します。
ユーザーがすべてのアカウントからログアウトしていることを示すには、トップレベル ナビゲーションまたは同一オリジン サブリソース リクエストで Set-Login:
logged-out
HTTP ヘッダーを送信します。
Set-Login: logged-out
または、IdP オリジンから JavaScript API navigator.login.setStatus('logged-out')
を呼び出します。
navigator.login.setStatus('logged-out');
これらの呼び出しは、ユーザーのログイン ステータスを logged-out
として記録します。ユーザーのログイン ステータスが logged-out
の場合、FedCM の呼び出しは IdP のアカウント リスト エンドポイントにリクエストを行うことなく、通知なく失敗します。
unknown
ステータスは、IdP が Login Status API を使用してシグナルを送信する前に設定されます。このステータスは、この API の出荷時にユーザーがすでに IdP にログインしているため、移行を改善するために導入されています。FedCM が最初に呼び出されるまでに、IdP がブラウザにこれを通知できない可能性があります。この場合、IdP のアカウント リスト エンドポイントにリクエストを行い、アカウント リスト エンドポイントからのレスポンスに基づいてステータスを更新します。
- エンドポイントから有効なアカウントのリストが返された場合は、ステータスを
logged-in
に更新し、FedCM ダイアログを開いてそれらのアカウントを表示します。 - エンドポイントからアカウントが返されない場合は、ステータスを
logged-out
に更新し、FedCM 呼び出しを失敗させます。
ユーザー セッションの有効期限が切れた場合ユーザーが動的ログインフローでログインできるようにします。
IdP がユーザーのログイン ステータスをブラウザに通知し続けても、セッションの有効期限が切れた場合などにステータスが同期されていない可能性があります。ログイン ステータスが logged-in
の場合、ブラウザは認証済みのリクエストをアカウント リストのエンドポイントに送信しようとしますが、セッションが利用できなくなったため、サーバーはアカウントを返しません。このようなシナリオでは、ブラウザでユーザーがダイアログ ウィンドウから IdP に動的にログインできます。
次の図のように、FedCM ダイアログにログインを促すメッセージが表示されます。
ユーザーが [続行] ボタンをクリックすると、ブラウザによって IdP のログインページのダイアログが開きます。
ログインページの URL は、IdP 構成ファイルの一部として login_url
で指定します。
{
"accounts_endpoint": "/auth/accounts",
"client_metadata_endpoint": "/auth/metadata",
"id_assertion_endpoint": "/auth/idtokens",
"login_url": "/login"
}
}
このダイアログは、ファーストパーティの Cookie が表示されている通常のブラウザ ウィンドウです。ダイアログ内での処理はすべて IdP により行われ、RP ページへのクロスオリジン通信リクエストに使用できるウィンドウ ハンドルはありません。ユーザーがログインすると、IdP は次のことを行う必要があります。
Set-Login: logged-in
ヘッダーを送信するかnavigator.login.setStatus("logged-in")
API を呼び出して、ユーザーがログインしたことをブラウザに通知します。IdentityProvider.close()
を呼び出してダイアログを閉じます。
Login Status API の動作は、こちらのデモでお試しいただけます。
- [IdP にアクセスしてログイン] ボタンをタップします。
- 任意のアカウントでログインします。
- [Account Status] プルダウンから [Session Expired] を選択します。
- [個人情報を更新] ボタンを押します。
- [RP にアクセスして FedCM を試す] ボタンをタップします。
モジュールの動作を通じて、IdP へのログインをモニタリングできます。
エラー API
Chrome が ID アサーション エンドポイントにリクエストを送信したとき(ユーザーが FedCM UI で [Continue as] ボタンをクリックした場合や、自動再認証がトリガーされたときなど)、IdP は正当な理由でトークンを発行できないことがあります。たとえば、クライアントが承認されていないと、サーバーが一時的に使用不能になります。現在、Chrome ではこのようなエラーが発生した場合、通知なくリクエストが失敗し、Promise を拒否して RP に通知します。
Error API では、Chrome は IdP から提供されたエラー情報を含むネイティブ UI を表示して、ユーザーに通知します。
IdP HTTP API
リクエスト時にトークンを発行できる場合、IdP は id_assertion_endpoint
レスポンスでブラウザにトークンを返すことができます。このプロポーザルでは、トークンを発行できない場合、IdP は 2 つの新しいオプション フィールドを含む「エラー」レスポンスを返すことができます。
code
url
// id_assertion_endpoint response
{
"error": {
"code": "access_denied",
"url": "https://idp.example/error?type=access_denied"
}
}
コードについては、IdP は OAuth 2.0 で指定されたエラーリスト(invalid_request
、unauthorized_client
、access_denied
、server_error
、temporarily_unavailable
)から既知のエラーのいずれかを選択するか、任意の文字列を使用できます。後者の場合、Chrome は汎用のエラー メッセージとともにエラー UI を表示し、コードを RP に渡します。
url
は、エラーに関する情報を含む人が読める形式のウェブページを識別し、エラーに関する追加情報をユーザーに提供します。ブラウザはネイティブ UI でリッチエラー メッセージを表示できないため、このフィールドはユーザーにとって有用です。たとえば、次のステップやカスタマー サービスの連絡先情報へのリンクなどです。ユーザーがエラーの詳細と修正方法について知りたい場合は、ブラウザの UI から表示されたページにアクセスすると、詳細を確認できます。URL は、IdP configURL
と同じサイトのものである必要があります。
try {
const cred = await navigator.credentials.get({
identity: {
providers: [
{
configURL: 'https://idp.example/manifest.json',
clientId: '1234',
},
],
}
});
} catch (e) {
const code = e.code;
const url = e.url;
}
自動選択フラグ API
mediation: optional
は、Credential Management API のデフォルトのユーザー メディエーション動作であり、可能な場合に自動再認証をトリガーします。ただし、自動再認証は、ブラウザしか認識できない理由で使用できない場合があります。使用できない場合、ユーザーは明示的なユーザー メディエーション(異なるプロパティを持つフロー)を使用してログインするよう求められる場合があります。
- API の呼び出し元から見ると、ID トークンを受け取ったユーザーは、それが自動再認証フローの結果だったかどうかを把握できません。そのため、API のパフォーマンスを評価し、それに応じて UX を改善することが困難になっています。
- IdP の観点からは、パフォーマンス評価で自動再認証が発生したかどうかを判別することはできません。また、明示的なユーザー メディエーションが関与しているかどうかは、より多くのセキュリティ関連機能のサポートに役立ちます。たとえば、ユーザーによっては、認証に明示的なユーザー メディエーションを必要とする上位のセキュリティ階層を選択する場合があります。IdP がこのようなメディエーションなしでトークン リクエストを受け取った場合は、リクエストの処理方法が異なる可能性があります。たとえば、RP が
mediation: required
で FedCM API を再度呼び出せるように、エラーコードを返します。
そのため、自動再認証フローを可視化することはデベロッパーにとって有益です。
Chrome は Auto-selected Flag API を介して、自動再認証が行われるか明示的なメディエーションが行われるたびに、[Continue as] ボタンをタップして IdP と RP の両方で明示的なユーザー権限を取得したかどうかを共有します。共有は、IdP/RP 通信のユーザー権限が付与された後にのみ行われます。
IdP の共有
ユーザーの権限後に IdP に情報を共有するため、Chrome では id_assertion_endpoint
に送信される POST
リクエストに is_auto_selected=true
を含めます。
POST /fedcm_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
account_id=123&client_id=client1234&nonce=Ct0D&disclosure_text_shown=true&is_auto_selected=true
取引規制対象者の共有
ブラウザは、IdentityCredential
を介して isAutoSelected
の RP と情報を共有できます。
const cred = await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/manifest.json',
clientId: '1234'
}]
}
});
if (cred.isAutoSelected !== undefined) {
const isAutoSelected = cred.isAutoSelected;
}
フィードバックを共有
フィードバックがある場合や、テスト中に問題が発生した場合は、crbug.com でお知らせください。
写真撮影: Girl with red hat(出典: Unsplash)