FedCM 更新:Continuation API 套裝組合的來源試用和 Storage Access API 自動授權

自 Chrome 126 起,開發人員可針對 適用於桌面的 Federated Credential Management API (FedCM) 功能 授權用途。這個套裝組合包含 Continuation API 和 Parameters API,可讓您啟用類似於 OAuth 授權流程的使用體驗 涉及識別資訊提供者 (IdP) 提供的權限對話方塊。套裝組合 包含其他變更,例如 Fields API、多個 configURL 及自訂 帳戶標籤。自 Chrome 126 起,我們還推出了 Storage Access API (SAA),可在使用者 曾使用 FedCM 成功登入。

來源試用:FedCM Continuation API 套裝組合

FedCM Continuation API 組合包含多個 FedCM 擴充功能:

Continuation API

使用者登入 RP,然後透過按鈕模式授權。

您可以查看 Glitch 上的 API 示範

Continuation API 可讓您 IdP 的 ID 斷言 端點 可選擇性傳回 FedCM 顯示的網址,讓使用者繼續執行 多步驟登入流程這可讓 IdP 要求使用者授予 超越現有的 FedCM UI 權限 例如存取使用者伺服器端資源

一般而言,ID 斷言端點會傳回 驗證。

{
  "token": "***********"
}

但使用 Continuation API 時,ID 斷言 端點 傳回 continue_on 屬性,其中包含絕對路徑或相對路徑 指向 ID 斷言端點的路徑

{
  // In the id_assertion_endpoint, instead of returning a typical
  // "token" response, the IdP decides that it needs the user to
  // continue on a pop-up window:
  "continue_on": "/oauth/authorize?scope=..."
}

瀏覽器收到 continue_on 回應後,會立即顯示新的彈出式視窗 ,並將使用者導向至指定路徑。

使用者與網頁互動後,例如授予進一步權限 如要與 RP 分享額外資訊,IdP 頁面可以呼叫 IdentityProvider.resolve()即可解決原始問題 navigator.credentials.get() 呼叫,並傳回權杖做為引數。

document.getElementById('allow_btn').addEventListener('click', async () => {
  let accessToken = await fetch('/generate_access_token.cgi');
  // Closes the window and resolves the promise (that is still hanging
  // in the relying party's renderer) with the value that is passed.
  IdentityProvider.resolve(accessToken);
});

接著,瀏覽器會自行關閉彈出式視窗,並將權杖傳回 API 呼叫。

如果使用者拒絕要求,您可以按照以下方式關閉視窗: IdentityProvider.close()

IdentityProvider.close();

如果使用者因故在彈出式視窗中變更帳戶 (例如 IdP 會提供「切換使用者」函式或委任情況下) 就會解析 呼叫的第二個引數則接收類似下列內容:

IdentityProvider.resolve(token, {accountId: '1234');

參數 API

Parameters API 允許 RP API 來為 ID 斷言 端點。 透過 Parameters API,RP API 即可將其他參數傳遞給 IdP, 要求基本登入以外的資源權限。使用者將授權 執行這類權限時,您可以透過 Continuation API

如要使用 API,請將參數新增為 params 屬性中的物件 navigator.credentials.get() 呼叫。

let {token} = await navigator.credentials.get({
  identity: {
    providers: [{
      clientId: '1234',
      configURL: 'https://idp.example/fedcm.json',
      // Key/value pairs that need to be passed from the
      // RP to the IdP but that don't really play any role with
      // the browser.
      params: {
        IDP_SPECIFIC_PARAM: '1',
        foo: 'BAR',
        ETC: 'MOAR',
        scope: 'calendar.readonly photos.write',
      }
    },
  }
});

params 物件中的屬性名稱會在前面加上 param_。在 上述範例,「params」屬性包含以 '1'foo 表示的 IDP_SPECIFIC_PARAM 格式為 'BAR'ETC'MOAR'scope 格式 'calendar.readonly photos.write'。 系統會將這些內容翻譯成 param_IDP_SPECIFIC_PARAM=1&param_foo=BAR&param_ETC=MOAR&param_scope=calendar.readonly%20photos.write 在要求的 HTTP 內文中:

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=234234&disclosure_text_shown=false&param_IDP_SPECIFIC_PARAM=1&param_foo=BAR&param_ETC=MOAR&param_scope=calendar.readonly%20photos.write

動態取得權限

一般而言,在使用者 ,而不是當開發人員覺得自己最容易實作。適用對象 例如在使用者即將取得相機存取權時,要求相機存取權 建議相片在使用者前往 網站。相同的做法也適用於伺服器資源。僅要求權限 適時適地執行所需工作這就是「動態授權」。

如要使用 FedCM 動態要求授權,IdP 可以:

  1. 使用 IdP 可以提供的必要參數呼叫 navigator.credentials.get() 例如 scope
  2. ID 斷言 端點 確認使用者已經登入,並以 continue_on 網址回應。
  3. 瀏覽器會開啟彈出式視窗,顯示 IdP 的權限頁面要求 符合要求範圍的其他權限。
  4. 由 IdP 透過 IdentityProvider.resolve() 授權後,視窗會 而 RP 的原始 navigator.credentials.get() 呼叫就會獲得 相關權杖或授權碼 正確的存取權杖

欄位 API

Fields API 可讓 RP: 宣告要向 IdP 提出的帳戶屬性,讓瀏覽器 在 FedCM 對話方塊中顯示適當的揭露 UI。也就是 IdP 的責任 將要求的欄位納入傳回的權杖。考慮這項要求 「基本設定檔」(在 OpenID Connect 與「範圍」中)。

小工具模式中的揭露訊息。
小工具模式中的揭露訊息。
,瞭解如何調查及移除這項存取權。
按鈕模式下的揭露訊息。
按鈕模式下的揭露訊息。

如要使用 Fields API,請在 fields 屬性中加入參數做為陣列 navigator.credentials.get() 呼叫。欄位可包含 'name''email''picture',但您可以展開以在

含有 fields 的要求如下所示:

let { token } = await navigator.credentials.get({
  identity: {
    providers: [{
      fields: ['name', 'email', 'picture'],
      clientId: '1234',
      configURL: 'https://idp.example/fedcm.json',
      params: {
        scope: 'drive.readonly calendar.readonly',
      }
    },
  }
  mediation: 'optional',
});

ID 斷言的 HTTP 要求 端點 包含 RP 指定的 fields 參數,並使用 disclosure_text_shown 參數設為 true (如果這不是回訪者); 在 disclosure_shown_for 參數中向使用者揭露瀏覽器:

POST /id_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=234234&disclosure_text_shown=true&fields=email,name,picture&disclosure_shown_for=email,name,picture

如果 RP 需要存取 IdP 提供的任何其他資料,例如 日曆,這個值應如上所述使用自訂參數進行處理。 IdP 會傳回 continue_on 網址以要求權限。

如果 fields 是空白陣列,要求應如下所示:

let { token } = await navigator.credentials.get({
  identity: {
    providers: [{
      fields: [],
      clientId: '1234',
      configURL: 'https://idp.example/fedcm.json',
      params: {
        scope: 'drive.readonly calendar.readonly',
      }
    },
  }
  mediation: 'optional',
});

如果 fields 是空白陣列,使用者代理程式就會略過揭露 UI。

小工具模式不會顯示揭露訊息。在按鈕流程中,系統會完全略過揭露聲明 UI。
小工具模式不會顯示揭露訊息。在按鈕流程中,系統會完全略過揭露聲明 UI。

即使使用者帳戶的回應 端點 未包含與 approved_clients 中 RP 相符的用戶端 ID。

在這個例子中,系統會將 disclosure_text_shown 傳送至 ID 斷言 端點為 false:

POST /id_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=234234&disclosure_text_shown=false

多個 configURL

多個 configURL 允許 IdP 才能容納多個 IdP 設定檔 accounts_endpointlogin_url知名地點的 檔案 做為設定檔

如果將 accounts_endpointlogin_url 新增至已知檔案, 系統會忽略 provider_urls,以便 IdP 支援多個設定檔。 如果兩者不同,provider_urls 會繼續生效,以便回溯 相容。

支援多個 configURL 的已知檔案應如下所示:

{
  "provider_urls": [ "https://idp.example/fedcm.json" ],
  "accounts_endpoint": "https://idp.example/accounts",
  "login_url": "https://idp.example/login"
}

這麼做可以:

  1. 維持與現有知名檔案回溯相容,並保持相容性 以及已經部署的舊版瀏覽器
  2. 擁有任意數量的設定檔,只要檔案都指向 相同的 accounts_endpointlogin_url
  3. 沒有機會在憑證擷取要求中新增資訊 對 accounts_endpoint 而言,則必須在 「.well-known」第二,自訂角色只能 套用至專案或機構

您可以選擇是否要支援多個 configURL,以及現有的 FedCM 導入程序可以保持不變

自訂帳戶標籤

自訂帳戶標籤允許 FedCM IdP 能為帳戶加註,讓 RP 透過指定標籤來篩選帳戶 設定檔使用網域提示 APILogin Hint API 而是透過 navigator.credentials.get() 呼叫,但自訂帳戶標籤 可指定設定檔來篩選使用者,這種做法特別適合用來 使用多個 configURL自訂帳戶標籤 與由 IdP 伺服器提供的內容不同 例如登入或網域提示

範例

IdP 分別支援消費者和企業的兩個 configURL。 取用者設定檔含有 'consumer' 標籤,以及企業設定檔 含有 'enterprise' 標籤。

完成這項設定後,知名檔案會包含 accounts_endpointlogin_url 允許多個 configURL

{
  "provider_urls": [ "https://idp.example/fedcm.json" ],
  "accounts_endpoint": "https://idp.example/accounts",
  "login_url": "https://idp.example/login"
}

當已知檔案提供 accounts_endpoint 時, 系統會忽略 provider_urls。RP 可以直接指向個別設定 接聽程式。navigator.credentials.get()呼叫

取用端設定檔位於 https://idp.example/fedcm.json,其中包含 accounts 屬性,使用 include 指定 'consumer'

{
  "accounts_endpoint": "https://idp.example/accounts",
  "client_metadata_endpoint": "/client_metadata",
  "login_url": "https://idp.example/login",
  "id_assertion_endpoint": "/assertion",
  "accounts": {
    "include": "consumer"
  }
}

企業設定檔位於 https://idp.example/enterprise/fedcm.json, 其中包括 accounts 屬性,該屬性會使用'enterprise' include

{
  "accounts_endpoint": "https://idp.example/accounts",
  "client_metadata_endpoint": "/enterprise/client_metadata",
  "login_url": "https://idp.example/login",
  "id_assertion_endpoint": "/assertion",
  "accounts": {
    "include": "enterprise"
  }
}

常見的 IdP 帳戶 端點 (本範例 https://idp.example/accounts) 會傳回一系列帳戶 包含標籤屬性,且每個帳戶的陣列中已獲派 labels。 以下是針對擁有兩個帳戶的使用者的回應範例。一種是 例如一般消費者

{
 "accounts": [{
   "id": "123",
   "given_name": "John",
   "name": "John Doe",
   "email": "john_doe@idp.example",
   "picture": "https://idp.example/profile/123",
   "labels": ["consumer"]
  }], [{
   "id": "4567",
   "given_name": "Jane",
   "name": "Jane Doe",
   "email": "jane_doe@idp.example",
   "picture": "https://idp.example/profile/4567",
   "labels": ["enterprise"]
  }]
}

當 RP 要允許 'enterprise' 使用者登入時,他們可以指定 'enterprise' configURL 'https://idp.example/enterprise/fedcm.json' navigator.credentials.get() 呼叫:

let { token } = await navigator.credentials.get({
  identity: {
    providers: [{
      clientId: '1234',
      nonce: '234234',
      configURL: 'https://idp.example/enterprise/fedcm.json',
    },
  }
});

因此,只有 '4567' 的帳戶 ID 可供使用者簽署 。瀏覽器會隱藏 '123' 的帳戶 ID,因此使用者不會看見這項資訊 不會向這個網站上的 IdP 不支援的帳戶提供帳戶。

來源試用:FedCM 做為 Storage Access API 的信任信號

Chrome 126 已開始將 FedCM 來源試用,做為 儲存空間存取權 API。取代為 本次異動後,先前透過 FedCM 授予權限後,便成為 自動透過儲存空間存取權核准儲存空間存取要求 API

當內嵌 iframe 要存取個人化資源時,這項功能就能派上用場: 舉例來說,如果 idp.example 已嵌入 rp.example 中,就必須顯示 個人化資源如果瀏覽器限制存取第三方 Cookie, 就算使用者透過 FedCM 登入 rp.example 嵌入 idp.example iframe 將無法要求個人化資源 因為請求不包括第三方 Cookie

為此,idp.example 必須透過 內嵌於網站中的 iframe,且只能透過 權限提示

使用 FedCM 做為儲存空間存取權的信任信號 API Storage Access API 權限檢查不只接受 都會收到儲存空間存取提示,但也會由 FedCM 提示。

// In top-level rp.example:

// Ensure FedCM permission has been granted.
const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://idp.example/fedcm.json',
      clientId: '123',
    }],
  },
  mediation: 'optional',
});

// In an embedded IdP iframe:

// No user gesture is needed to call this, and the call will be auto-granted.
await document.requestStorageAccess();

// This returns `true`.
const hasAccess = await document.hasStorageAccess();

使用者透過 FedCM 登入後,只要 已啟用 FedCM 驗證。也就是說,一旦使用者中斷連線 要求權限時會出現提示

參與來源試用

如要在本機試用 FedCM Continuation API 套件,請開啟 Chrome 標記 Chrome 126 以上版本:chrome://flags#fedcm-authz。或試用 FedCM 以信任信號當做信任信號,然後透過 #fedcm-with-storage-access-api (適用於 Chrome 126 以上版本)。

這些功能也可做為來源試用。來源試用計畫可讓你試用新功能,並就可用性、實用性和成效提供意見回饋。詳情請參閱「開始使用來源試用」一文。

試用 FedCM Continuation API 組合來源 試用期 建立兩個來源試用權杖:

如果您想啟用 Continuation API 及 流程,啟用按鈕模式 API 來源 試用 其他情況:

如要試用 FedCM 做為 Storage Access API 來源的信任信號 試用

Continuation API 組合來源試用以及 FedCM 做為 Storage Access API 來源試用是從 Chrome 126 開始提供。

為 RP 註冊第三方來源試用

  1. 前往來源試用註冊頁面。
  2. 按一下「Register」按鈕,並填寫表單以要求權杖。
  3. 將 IdP 的來源輸入為「Web Origin」
  4. 檢查第三方比對,透過 JavaScript 在其他來源插入權杖。
  5. 按一下 [提交]。
  6. 將核發的權杖嵌入第三方網站。

如要將權杖嵌入第三方網站,請將下列程式碼新增至 IdP 的 從 IdP 來源提供的 JavaScript 程式庫或 SDK。

const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);

TOKEN_GOES_HERE 替換成您自己的權杖。