作者 | Dan Moore
譯者 | 劉雅夢
策劃 | 丁曉昀
聯(lián)邦憑證管理(federalcredential Management,FedCM)API 是一個提議中的 Web 規(guī)范,可能會影響幾乎所有通過瀏覽器登錄應用程序的人。FedCM 在 W3C 內部開發(fā),旨在通過引入瀏覽器原生的方式來處理聯(lián)合登錄,從而創(chuàng)建一個更加保護隱私的 Web。當一個應用程序將登錄過程委托給另一個稱為身份提供者的應用程序時,就會發(fā)生聯(lián)合登錄。
FedCM 最初的動機是為聯(lián)合登錄提供更好的基礎,并得到瀏覽器的支持。與一般用途的 Web 原語(如重定向、iframe 和第三方 cookie)不同,部分原因是這些原語也被廣告商用來在網絡上追蹤用戶,開發(fā)者可以使用原生 API。雖然 谷歌 Chrome 將阻止第三方 cookies 的決定權交給了用戶,但其他瀏覽器 仍然默認阻止所有或大多數第三方 cookies。
FedCM 專注于用戶隱私,并利用瀏覽器的原生 UI 元素,旨在構建一個更加一致和安全的登錄體驗,并解決沒有瀏覽器功能就無法解決的問題。這些問題包括可用的身份提供者太多(NASCAR 標志問題)和發(fā)現身份提供程序。
如果你使用第三方社交提供商登錄 Web 應用程序,你可能很快就會使用到 FedCM。大多數使用“使用谷歌登錄”和谷歌身份服務庫的開發(fā)者都在使用 FedCM;該庫在 2024 年更新為使用此 API。
Web 應用登錄的歷史
雖然最早的網站是靜態(tài)頁面,但向不同用戶提供不同內容的價值很快導致了在顯示內容之前進行身份驗證。Web 應用程序開始添加身份驗證。這種方法將用戶數據隔離開來,要求他們在應用程序之間重新輸入憑據,并給每個應用程序增加了安全負擔。
1994 年,Netscape Navigator 團隊發(fā)明了使用中央認證服務器的基于 cookie 的登錄;這解決了單服務器認證的一些問題。然而,這種解決方案是有限的,因為 cookie 不會在域之間共享。這種分離是網絡安全模型的關鍵組成部分。雖然嵌入式 iframe 可以繞過這個問題,但它們存在安全問題,尤其是 點擊劫持。
隨著 2002 年 SAML 1.0 的發(fā)布,第一個基于重定向的標準化登錄流程得以實施。SAML 使用重定向和簽名 XML 文檔確保用戶已經通過身份驗證,從而允許應用程序安全地委托認證過程。其他研究同一問題的團隊修訂了 SAML,2.0 版本在 2005 年發(fā)布。
OAuth 和 OIDC 在 2012 年至 2014 年期間發(fā)布,并更新了 SAML 的格式和機制,但利用了相同的重定向和簽名文檔方法。目前,大多數應用程序要么將認證嵌入到應用程序中,接受 1990 年代類型的安全和實現問題,要么與中央身份驗證服務器聯(lián)合。這種中央認證服務器可能并不托管在與原始應用程序相同的域上。因此,因此,如果沒有第三方 cookie,諸如基于靜默 iframe 的刷新或 JavaScript 請求等認證功能可能會失敗。但是,第三方 cookie 也允許廣告商和平臺在網絡上追蹤用戶。用戶可以在整個互聯(lián)網上被追蹤,捕獲不同站點和應用程序的行為。
OIDC 和 SAML 使用的基于重定向的機制也導致了上述提到的 NASCAR 標志問題。網站必須枚舉它們支持的身份提供者。由于頁面上的空間有限,這有利于少數大型提供者,從而阻礙了應用程序允許用戶選擇自己的身份提供商。保護用戶隱私和通過瀏覽器提供更好的用戶體驗的目標導致了 FedCM 項目。讓我們來看一下這個項目的時間線。
聯(lián)邦憑證管理時間線
在谷歌和 Chrome 團隊推廣的第三方 cookie 更改的背景下,審查 FedCM 工作是很重要的。在谷 歌宣布網絡隱私重要性 之后不久,該項目的工作就開始了。
第一個提交到將成為聯(lián)合身份管理存儲庫的存儲庫是在 2020 年 3 月(最初被稱為 WebID)。W3C 社區(qū)組在 2021 年開始,工作組成立于 2024 年。(社區(qū)組孵化想法,工作組發(fā)布建議)。
在 2022 年,該項目由谷歌員工引入 Firefox。它被認為是一個積極的改變,到 2022 年底,初始原型被添加到 Firefox 中。雖然第三方 cookie 棄用的路徑取得了 前進了一步又后退了一步,但 FedCM 工作一直在繼續(xù)。不過,這不僅僅是規(guī)范在演變。瀏覽器中的代碼已經推出。部分 FedCM 功能在 2022 年發(fā)布的 Chrome 和 Edge 108 中發(fā)布。在 2025 年,在 Firefox 中添加了一個完整版本的缺陷跟蹤。
聯(lián)邦憑證管理(FedCM)的初步支持在 2023 年被添加到 Selenium 中,并且是 playwright 的一個開放功能請求。該規(guī)范有一個關于瀏覽器自動化的頂級部分,因此人們理解這很重要。工作組在 2024 年 8 月發(fā)布了一個工作草案規(guī)范,但在發(fā)布候選版本之前還有很多工作要做。有一個編輯草案可供使用,并且定期更新。
讓我們來看一下 FedCM 提供的特性。
聯(lián)邦憑證管理功能
在我們研究 FedCM 功能之前,先了解一些有用的定義:
RP 或依賴方:這是用戶通過瀏覽器嘗試訪問的應用或數據的網站。這個應用觸發(fā)了一個認證事件。
IDP 或身份提供者:這是持有身份信息并與瀏覽器交互的持有者。在上面我稱之為中央認證服務器。
用戶代理:這只是瀏覽器的一個花哨術語。
這些是由 FedCM 規(guī)范使用的術語,因此我們將在本文的其余部分使用它們。讓我們來看一下用戶流程,包括基于重定向的和使用 FedCM 的用戶流。
基于重定向流的用戶流程圖
這是用戶第一次使用基于重定向的工作流程登錄。
當用戶第二次登錄時,它們被反彈到 IDP。但由于他們的 cookies 是有效的,所以他們看不到登錄表單。
使用 FedCM 的登錄流程
用戶第一次使用 FedCM 登錄時的體驗取決于依賴方請求的具體細節(jié),但通常情況下,IDP 會用 iframe 提示登錄憑據。
該圖顯示了“被動”模式的流程,它需要最少的用戶交互。
在步驟 12 中,一旦用戶代理接收到令牌,FedCM 部分就完成了。RP 可能還有更多事情要做。
當用戶第二次使用 FedCM 登錄時,奇跡就發(fā)生了。當用戶以前使用過 FedCM 并且沒有超過一個帳戶時,他們不會被提示登錄,而是在不離開 RP 的情況下自動重新認證:
FedCM 規(guī)范的作者考慮了其他登錄情況,包括:
在這臺設備上有多個賬戶登錄到認證提供者
無效的用戶賬戶
當用戶注銷了依賴方但沒有注銷身份提供者
如果用戶最近注銷了身份提供者
下面是用戶看到的一個例子:
瀏覽器支持
根據 Cloudflare 提供的按市場份 額劃分的瀏覽器列表,這里列出了市場份額超過 1% 的瀏覽器以及它們對 FedCM 的支持程度。
Chrome:從版本 136 開始完全支持。Chrome 團隊在 FedCM 工作組中非?;钴S。
Safari:支持這項工作,但截至撰寫本文時尚未發(fā)布實現。 WebKit 標準頁面上頁沒有提及。
Edge:從版本 136 開始完全支持。
Firefox:正在努力支持,但截至本文發(fā)布時尚不支持。這是發(fā)布此功能的缺陷跟蹤。Firefox 團隊在 FedCM 工作組中很活躍,但從 2025 年 8 月起暫停實施。
Samsung Internet:從版本 26 開始幾乎完全支持。
Opera:從版本 108 開始幾乎完全支持,其中一個特性還在預覽中。
Brave:在 2023 年提到了對這項工作的支持,一個開放的 GitHub 問題提到了它,但最近沒有動靜。
IDP 支持
對身份提供者的支持正在增長,但肯定不是普遍的。根據 2024 年秋季的一份報告,以下身份提供者支持 FedCM:
Google(這是他們的 .well-known 文件)
NetID(GMX/Web.de)
Shopify
Seznam(一個捷克網絡門戶和搜索引擎)
Mobage(一個游戲門戶和社交網絡)
Times Internet(一家印度跨國技術公司)
AMedia(一家報紙公司)
Ory(一個支持 FedCM 的基礎設施提供者)
人們對 FedCM 工作組也有更廣泛的興趣,工作組參與者名單中包括許多 IDP。
RP 支持
支持 FedCM 的 Web 應用程序更難追蹤,但包括:
Pinterest
Kayak
Booking.com
Realtor.com
如果你想知道一個 RP 是否支持 FedCM,打開瀏覽器檢查器中的登錄頁面并搜索嵌入在 JavaScript 中的字符串“IdentityCredential
”。
支持的用例
FedCM 專注于以下用例:
用戶登錄,以一種注重隱私和安全的方式驗證依賴方的用戶在身份提供者處擁有賬戶。
將用戶賬戶從瀏覽器管理的列表中斷開連接。
還有其他與認證相關的用例,它們不是 FedCM 的重點,但與之相鄰:
注冊 / 注冊流程由一個擴展處理,允許用戶使用 FedCM 注冊賬戶。帳戶創(chuàng)建是在 IDP 和瀏覽器之間嚴格處理的。
注銷用例也被覆蓋了。當請求登錄賬戶時,如果 IDP 沒有提供賬戶,用戶將被注銷。IDP 也可以調用 API 將用戶標記為已注銷。
賬戶恢復和憑證管理不是由 FedCM 或其擴展處理的。
實現細節(jié)
FedCM 規(guī)范尚未最終確定。雖然本實現指南在發(fā)布時是正確的,但可能存在不準確之處。查看規(guī)范并與支持的瀏覽器進行測試是確保你的實現能工作的最佳方式。
瀏覽器、IDP 和 RP 都有實現責任。本文不打算介紹瀏覽器實現;如果你您正在構建瀏覽器,請 查看規(guī)范。
網站實現細節(jié)
登錄
網站 /RP 通過使用身份提供者 API 開始認證過程。測試 API 支持并啟動流程(添加按鈕處理程序,如下所示,或在頁面加載后觸發(fā)登錄):
$('
-in').addEventListener('click', async e => {
try {
if ('IdentityCredential' in window) {
await signIn();
} else {
throw new Error('FedCM not supported.');
}
} catch (error) {
// 跳轉到 IDP
}
});
你應該測試 FedCM 支持,因為瀏覽器支持是不完整的,用戶可以禁用它。如果需要,可以回退到其他方法。
讓我們看看signIn
函數:
const signIn = async () => {
const credential = await navigator.credentials.get({
identity: {
// 指定此依賴方支持的 IdP 或 idps
providers: [{
configURL: 'https://accounts.idp-1.example/config.json',
mode: 'active',
params: {
scope: 'drive'
},
mediation: 'optional',
clientId: 'CLIENT_ID1'
},
{
configURL: 'https://accounts.idp-2.example/config.json',
mode: 'active',
params: {
scope: 'drive'
},
mediation: 'optional',
clientId: 'CLIENT_ID2'
}
]
}
}, );
const {
token
} = credential;
該請求傳遞客戶端標識符和配置 URL,這有助于 IDP 識別用戶。讓我們看看其他參數。mode
可以是“主動”或“被動”?!爸鲃印闭埱笮枰脩艚换?,而被動請求則不需要,具體取決于調解值。調解有四個已定義的值,決定了登錄過程可以在多大程度上無需用戶交互進行。params
包含傳遞給登錄進程的額外參數。例如,使用loginHint
指定要顯示的帳戶,或使用nonce
來防止重放攻擊。
然后瀏覽器將向用戶顯示所有請求和正確響應的 IDP。RP 可以通過查看credential.configURL
來檢查用戶登錄到了哪一個,它告訴 RP 瀏覽器成功連接到哪個 IDP。有效的令牌是成功認證的結果。在接收到令牌后,RP 必須使用它。該邏輯取決于應用程序。一旦獲得令牌,FedCM 流程就完成了。
斷開連接
一旦使用了 IDP,就會在瀏覽器中存儲其記錄。如果這是一個公共瀏覽器或賬戶是敏感的,用戶可能想要斷開連接。這是通過使用以下 JavaScript 完成的:
async function handleIdentityCredentialDisconnect() {
// 檢查 IdentityCredential API 是否存在
if (!window.IdentityCredential) {
console.error('IdentityCredential API is not available in this browser');
return;
}
try {
// 調用 disconnect 并等待 promise
const result = await IdentityCredential.disconnect({
configURL: 'https://idp.com/config.json',
clientId: 'rp123',
accountHint: 'account456'
});
console.log('IdentityCredential disconnect successful:', result);
return result;
} catch (error) {
console.error('IdentityCredential disconnect failed:', error);
throw error; // 如果你希望調用代碼處理它,則重新拋出
}
}
// 使用示例:
handleIdentityCredentialDisconnect()
.then(result => {
console.log('Disconnect operation completed successfully');
})
.catch(error => {
console.error('Disconnect operation failed:', error);
});
斷開連接可能由于各種原因而失敗,例如用戶在瀏覽器中禁用了 FedCM。接下來讓我們看看 IDP 的實現。
IDP 實現細節(jié)
IDP 需要實現規(guī)范的 HTTP API 部分。你可以查看 2024 年 8 月的草案和最新的編輯草案。由于所提議的標準正在迅速發(fā)展,因此在實現 FedCM 時,最好的選擇是使用你想要支持的瀏覽器進行測試,并參考編輯的草案和谷歌 FedCM 文檔。
實現細節(jié)
認證提供者需要提供幾個文件。讓我們假設認證提供者托管在“auth.example.com”。以下是 FedCM 工作所需的文件:
"https://example.com/.well-known/web-identity"
"https://auth.example.com/config.json"
"https://auth.example.com/accounts"
"https://auth.example.com/client_metadata"
"https://auth.example.com/id_assert"
"https://auth.example.com/login"
"https://auth.example.com/logout"
讓我們逐一研究一下。
.well-known 文件
首先是.well-known
文件,它有一個明確的位置,但如果 RP(依賴方)和 IDP(身份提供方)是同一個站點,則它不是必須的。它必須位于 IDP 域名的根目錄下這個路徑。如果你的 IDP 存在于"idp.example.com
",那么這個文件必須存在于"example.com/.well-known/web-identity
"。
這個文件位于根域名是為了保護 RP 的身份:
“在 IDP 域名根目錄存在一個文件是強制執(zhí)行的,以確保文件名不會引入關于正在訪問的 RP 的指紋。” —— https://w3c-fedid.github.io/FedCM/-fingerprinting
關于這個文件內容的一個示例:
{
"provider_urls": [
"https://auth.example.com/config.json"
],
"accounts_endpoint": "https://auth.example.com/accounts",
"login_url": "https://auth.example.com/login"
}
如果存在accounts_endpoint
和login_url
,它們必須與下面提到的配置文件中的值匹配。如果配置文件中存在客戶端元數據端點,則這些字段是必需的。
配置文件
在請求了.well-known
文件之后,瀏覽器會請求適當的配置文件。RP 可以請求與provider_urls
數組中不同的配置文件,只要accounts_endpoint
和login_url
與 well-known 文件中的相同即可。這允許為 staging 和 prod 環(huán)境使用不同的配置文件。
配置文件樣例內容如下:
{
"accounts_endpoint": "/accounts",
"client_metadata_endpoint": "/client_metadata",
"id_assertion_endpoint": "/id_assert",
"login_url": "/login",
"disconnect_endpoint": "/logout",
"branding": {
"background_color": "green",
"color": "0xFFEEAA",
"icons": [
{
"url": "https://idp.example/icon.ico",
"size": 25
}
],
"name": "Example"
}
}
讓我們更詳細地看看這些字段。
accounts_endpoint
accounts_endpoint
處的代碼負責返回用戶在 IDP 上登錄的賬戶列表。它將接收帶有SameSite=None
的 cookies、一個Sec-Fetch-Dest
頭部,以及其他任何內容的 cookie(沒有指示哪個 RP/ 網站正在請求用戶登錄)。IDP 應在驗證Sec-Fetch-Dest
頭部和 cookies 后返回。它應該返回如下所示的 JSON:
{
"accounts": [
{
"id": "1234",
"given_name": "John",
"name": "John Doe",
"email": "john_doe@idp.example",
"picture": "https://idp.example/profile/123",
"approved_clients": [
"123",
"456",
"789"
],
"login_hints": [
"john_doe"
],
"domain_hints": [
"idp.example"
]
},
{
"id": "5678",
"given_name": "Johnny",
"email": "johnny@idp.example",
"picture": "https://idp.example/profile/456",
"approved_clients": [
"abc",
"def",
"ghi"
],
"login_hints": [
"email=johhny@idp.example",
"id=5678"
],
"domain_hints": [
"idp2.example"
],
"label_hints": [
"l1"
]
}
]
}
對于返回的帳戶,有各種過濾選項可用。login_hint
和domain_hint
允許 RP 只請求匹配某些值的帳戶。如果一個 RP 只想要“idp.example”域,則只返回 id 為“1234
”的帳戶。label_hints
匹配配置中的值,也限制帳戶。不同之處在于label_hints
不需要 RP 的配置,而是使用 RP 請求的配置文件中的account_label
進行配置。
規(guī)范 中定義的其他字段。
client_metadata_endpoint
該端點接收客戶端標識符,并返回服務條款、隱私策略和其他元數據。支持此端點是 可選 的,但對創(chuàng)建新帳戶很有幫助。
id_assertion_endpoint
該端點接受與 RP 對應的 client_id 和與終端用戶對應的帳戶 id,以及其他一些參數,包括用戶是否自動登錄。請求包括 RP 源、cookies 和 Sec-Fetch-Dest 報頭。
該端點返回一個令牌,以及 continue_on 字段中的 URL(可選)。下面是一個例子:
{
"token": "..."
}
如果提供了 continue_on 字段,它包含“用戶代理將在彈出窗口中打開該 URL 以完成認證過程”。當 IDP 需要在認證完成之前執(zhí)行其他步驟時,請使用此字段。
login_url
如果用戶未登錄,瀏覽器會顯示這個 IDP URL。此頁面不知道引起登錄請求的 RP 的任何信息,以保護隱私。此 URL 也能處理其他認證用例,例如 MFA 挑戰(zhàn)或帳戶恢復。但是,FedCM 根本沒有定義這些流。當 IDP 對用戶進行了滿意的認證后,它可以發(fā)送 Set-Login: logged-in 標頭或調用 navigator.login。在 HTML 頁面上 setStatus("logged-in"),然后調用 IdentityProvider.close() 關閉窗口。
disconnect_endpoint
這是用戶代理發(fā)出斷開連接請求的 URL,因此 IDP 不再存儲在瀏覽器中。它獲取表示 RP 的 client_id 和包含要斷開連接的帳戶 id 的 account_hint。它還獲取 IDP cookies 和 Sec-Fetch-Dest 報頭。它應該使用已斷開連接的帳戶 id 進行響應。這可能與 account_hint 中的帳戶 id 不同。
branding
品牌字段允許 IDP 控制 FedCM 登錄用戶體驗的外觀,包括名稱、顏色和圖標。它是最小化的,由瀏覽器實現控制。
安全措施
如上所述,使用 FedCM 的主要原因是,對于現代網絡認證至關重要的 cookies 和重定向原語可以用來跟蹤用戶。FedCM 通過幾種方式避免了這一點。它限制了瀏覽器調用的每個端點可用的信息,只提供所需的信息。下面的表格顯示了從 規(guī)范 中每個端點發(fā)送的內容。
為了防止合法的瀏覽器請求被濫用,必須在每個非彈出式 FedCM 瀏覽器請求中檢查 Sec-Fetch-Dest 報頭。此檢查必須由 IDP 完成,值應該始終為 webidentity。Cookies 發(fā)送時帶有 Samesite=None,這可能看起來令人擔憂。但是這些請求是由瀏覽器嚴格控制的,并且該設置允許跨域認證,其中 RP 和 IDP 位于不同的域。還有一整節(jié)是關 于規(guī)范作者考慮 并記錄的安全措施的。
什么東西在不斷變化
有很多。
雖然它已經在 Chrome 和 Edge 上推出了,但從瀏覽器端和 IDP 端來看,還有很多工作要做。有兩項努力正在發(fā)生變化:
IDP 注冊,旨在使其更容易地增加 IDP 支持 FedCM 的數量。
委托,這提高了聯(lián)合登錄的隱私方面,特別是確保 IDP 無法知道哪個 RP 委托了認證給它。
我預計 FedCM 將獲得越來越多的動力,但在成為發(fā)布的 w3c 標準之前,還需要完成很多個月甚至幾年的工作。你可以通過加入 W3C 工作組或 W3C 社區(qū)組 來參與。有定期的視頻會議,你也可以查看正在進行的規(guī)范。你可以從這個 會議演 講中了解更多關于瀏覽器 UX 變化的信息。最后,你可以在 FedCM GitHub 倉庫中提交問題并關注 PRs。
對利益相關方的影響
讓我們看看對主要利益相關方的影響。
開發(fā)者
使用 FedCM 是一個簡單的實現任務:調用原生瀏覽器 API。當使用時,FedCM 允許用戶在不離開網絡應用的情況下在 IDP 上進行認證,使用一種原生的、安全的、注重隱私的方法。一些值得關注的問題:
覆蓋范圍
FedCM 是一個不斷發(fā)展的提議標準,目前在許多瀏覽器(包括 Safari 和 Firefox)上都不可用。雖然 Chrome 擁有大部分桌面瀏覽器市場份額,但這可能不足以證明添加此功能的合理性。缺乏 Safari 的支持意味著 FedCM 在桌面上不會是一個完整的解決方案,更不用說移動設備了。計劃維護一個后備登錄方法。
替代方法
FedCM 要成為唯一的登錄方法還有很長的路要走。就像魔術鏈接或密碼一樣,網站必須提供其他方式讓用戶登錄,這既是因為瀏覽器的支持,也是因為用戶的偏好。
品牌化
認證和注冊是應用程序的前門。通過使用 FedCM,你減少了摩擦,但放棄了 UX 控制。這不僅包括外觀和感覺,還包括提供其他認證方法,如 SAML 或 OIDC。
身份提供商
作為身份提供商實施 FedCM 并不像網站開發(fā)者那樣簡單,但回報也更高。雖然端點定義得相當清楚,但必須遵循安全規(guī)則,如 cookie 和頭部檢查。到目前為止,FedCM 工作主要由瀏覽器供應商推動,因此 IDP 實施指南沒有得到應有的關注。然而,支持 FedCM 可以為身份提供商提供與支持其他安全、注重隱私的認證方法相同的好處。通過支持這一提議的標準,IDP:
讓用戶在沒有任何重定向的情況下登錄
增加最終用戶的登錄選項
如果瀏覽器最終淘汰第三方 cookies,做好準備
可以幫助 RP 滿足 GDPR、CCPA 和其他數據保護要求等隱私法規(guī)
最終用戶
要使用 FedCM,最終用戶必須改變他們的登錄行為,但由于分階段推出,應該能夠以他們認為合適的方式管理這一點。將會有很長一段時間的退路,所以如果最終用戶對瀏覽器彈出窗口感到困惑,他們可以退回到更正常的登錄體驗。目前尚不清楚非瀏覽器工具(如密碼管理器)將如何與 FedCM 互動,盡管對用戶代理自動化的顯著支持意味著這些工具可能能夠這樣做。
結 論
FedCM 至關重要。這個提議的標準已經在大多數桌面流量上得到了支持,并且正在積極開發(fā)中,工作組中有三十個組織參與。然而,大多數人會從等待另一個草案發(fā)布和 API 固化中受益。如果你喜歡生活在邊緣,并且谷歌是需要支持的身份提供者,你現在就可以使用 FedCM。最后,參與塑造這個提議的標準。如上所述,有會議和其他機會可以貢獻。
感謝 Sam Goto 和 Bruno Couriol 對本文的審閱。
https://www.infoq.com/articles/federated-credentials-management-w3c-proposal/
聲明:本文為 InfoQ 翻譯,未經許可禁止轉載。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.