公共用戶端與機密用戶端的差別是什麼?
本文以 Logto 應用程式為例,揭示在 OAuth 中公共用戶端和機密用戶端的差別。
本文以 Logto 應用程式為例,揭示在 OAuth 中公共用戶端和機密用戶端的差別。
當使用 Logto 建立應用程式時,你會注意到有幾種不同的應用程式類型可供選擇,包括單頁應用程式(SPA)、原生應用程式和傳統網頁應用程式。直觀地從名稱中可以明白,原生應用程式運行在常見於手機等設備的操作系統上。然而,什麼是 SPA 和傳統網頁應用程式呢?為什麼我們需要區分這些不同類型的應用程式?本文將揭曉這些問題的答案。
在開始之前,我們需要簡要介紹一些概念。
OAuth 是一種用於存取委派的開放標準,通常用於讓網際網路用戶在不提供密碼的情況下授權網站或應用程式存取他們在其他網站上的資訊。
在最近十年間,它漸漸成為標準授權流程,並被大多數公司如 Google、Meta、Microsoft 等廣泛接受。目前使用的版本是 OAuth 2.0。
在 OAuth 的背景下,我們先前提到的應用程式被稱為用戶端。當獲得資源擁有者(通常是終端用戶)的授權後,它們可以請求訪問受保護的資源。
OAuth 定義了兩種類型的用戶端,根據它們是否可以維護用戶端憑證的機密性。
能夠維持其憑證機密性的用戶端(例如,實施在具有限制存取到用戶端憑證的安全伺服器上的用戶端)或能夠通過其他方式進行用戶端的安全身份驗證的用戶端。
無法維護其憑證機密性的用戶端(例如,運行在資源擁有者設備上的用戶端,如原生應用程式或基於網頁的應用程式),同時也無法通過任何其他方式安全地進行用戶端身份驗證。
有了上面提到的背景知識,讓我們來看看在 Logto 的背景下,SPA、原生應用程式和傳統網頁應用程式的含義,以及它們是否被視為公共用戶端或機密用戶端。
SPA 的客戶端代碼從網頁伺服器下載,並在資源擁有者的設備上的用戶代理(如網頁瀏覽器)中執行。協議數據和憑證容易被資源擁有者訪問(且通常可見)。
原生應用程式安裝並運行在資源擁有者的設備上。協議數據和憑證對資源擁有者是可存取的。一般假設應用程式內任何用戶端身份驗證憑證都可以被提取出來。
傳統網頁應用程式是在網頁伺服器運行的用戶端。資源擁有者通過在其設備上的用戶代理中呈現的 HTML 用戶界面訪問用戶端。用戶端憑證以及發放給用戶端的任何訪問令牌都儲存在網頁伺服器上,不會被揭露或資源擁有者不可存取。
所以,我們可以清楚地看到,SPA 和原生應用程式是公共用戶端,而傳統網頁應用程式是機密用戶端。
你可能會發現當在 Logto 中創建 SPA 或原生應用程式時,沒有應用程式密碼,而傳統網頁應用程式則有應用程式 ID 和應用程式密碼。這是因為公共用戶端的密碼無法保證其安全性。
在開發 OAuth 應用程式時,第一步是將用戶端註冊到 OAuth 服務提供者。用戶端註冊涉及提供有關應用程式的詳細資訊,例如其名稱和重定向 URI。然後,OAuth 服務提供者生成用戶端 ID 和用戶端密碼,這被視為應用程式的憑證。
用戶端 ID 被視為公共資訊,並在 OAuth 過程中與用戶共享。它通常包含在授權 URL 中並對終端用戶可見。
另一方面,用戶端密碼是應用程式的密碼,必須保密。在 OAuth 流程中,它用於交換授權碼(假定是授權碼流程)以獲取訪問令牌。用戶端密碼的存在確保只有註冊的應用程式能完成訪問令牌的交換。
如前所述,公共用戶端的用戶端密碼無法保證其安全,攻擊者可能獲得用戶端憑證並假冒用戶端來存取受保護的資源,這在任何情況下都是不可接受的。
PKCE(代碼交換的證明金鑰)通過在每次授權流程開始時臨時生成一個代碼校驗器,然後將其儲存在本地並哈希生成代碼挑戰,發送到授權伺服器的方法解決了這個問題。當交換訪問令牌時,代碼校驗器將再次被發送至授權伺服器。授權伺服器驗證代碼校驗器和代碼挑戰是否匹配,這確保了公共用戶端未被假冒。
PKCE 中的代碼校驗器實際上作為動態用戶端密碼。其安全性由哈希算法的不可逆性保證。
在本文中,我們討論了 OAuth 中機密用戶端和公共用戶端的概念。我們了解到機密用戶端具有保密的能力,可以安全地儲存敏感資訊,而公共用戶端則缺乏這一能力。我們在 Logto 的產品實踐背景下,檢查了這兩種類型用戶端的例子,包括傳統網頁應用程式、SPA 和原生應用程式。
我們還討論了 OAuth 中的用戶端註冊流程以及用戶端 ID 和用戶端密碼的角色。
此外,我們發現公共用戶端在安全存放用戶端密碼方面面臨限制。為了克服這一限制,我們介紹了 PKCE(代碼交換的證明金鑰),這是一個允許公共用戶端在不需要用戶端密碼的情況下安全交換授權碼的 OAuth 擴展。
我們的產品 Logto 是一個全面的 CIAM 解決方案,遵循 OAuth 和 OIDC 協議的最佳實踐,以確保各階段的安全性,包括採用 PKCE 來保護公共用戶端的安全。