Native App

第一天在定義範圍時,提到只討論 Web 上的身分驗證。而在鐵人賽即將結束的這一刻,來聊聊 Native App 上該怎麼透過 Web 做身分驗證吧!

首先,先定義什麼是 Native App,參考 RFC 8252 的說明,Native App 可以是下列其中之一:

  • 行動裝置上發布的應用程式,包括 Android 平台與 iOS 平台上的 App
  • 桌面軟體,包括 Windows 平台、Linux 平台與 MacOS 平台上的 App
  • 基於 Web 技術,但作為行動裝置或桌面軟體發布的應用程式,包括 Electron、Unity、React Native、Cordova 等

舉幾個例子:最近蠻多人討論的 Notion,或是跨 Apple 全平台的寫筆記軟體 Bear,都屬於 Native App。

Native App 的身分驗證方式

再回頭看一次身分驗證可以怎麼做

以現今的 Native App 來說,這三種身分驗證情境都是有可能遇到的,但帳號密碼驗證,或 API 身分驗證的信任伺服器的形式,情境都是單純的。比較有問題的情境是在 OAuth2 授權與第三方身分驗證上的,因為這兩個情境都不希望讓第三方應用程式知道太多有關使用者的資訊,但建構在 Native App 上就容易取得較多權限,導致不容易達成這個前提。

不要使用嵌入式 User Agent

OAuth2 在 RFC 6749 section 9 有提到 Native App 如何跟授權服務器互動,但 RFC 8252 section 8.12 則明確說明了使用嵌入式 User Agent 的缺點。

  1. 通常使用者無法透過嵌入式 User Agent 看到網址、TLS 憑證狀態等等。這讓攻擊者更容易創造出惡意的釣魚 App,而且使用者完全無法確認。
  2. Native App 有辦法存取使用者憑證以及 Cookie。這就違反了 [OAuth][Day 23] 設計的初衷--不想讓使用者憑證暴露給第三方。
  3. 嵌入式 User Agent 的狀態是獨立的,不同的嵌入式 User Agent,都得重新做一次身分驗證。這是極差的使用者體驗。

實際流程

目前的最佳做法為,使用 Authorization Code Grant 作為授權的流程。流程啟動是從外部瀏覽器(如 Safari 或 Chrome)發出授權請求開始的,而在外部瀏覽器授權完後,直接透過 URI 轉導到應用程式裡。

另外為了避免授權碼攔截攻擊,授權伺服器與 Client 必須實作 PKCE(Proof Key for Code Exchange)以確保 code 不會被惡意 App 攔截並使用。

URI 註冊的方法

RFC 裡面有提到 URI 註冊的方法有三個:

  1. 使用自定義 URL schemes,如
    com.example.app:/oauth2redirect/example-provider
  2. 有些系統支援 HTTPS scheme 直接轉導到 App 裡,則也可以使用這個方案,如
    https://app.example.com/oauth2redirect/example-provider
  3. 最後則是在本機直接起服務來接 code,這方案常見在桌機系統,如
    https://app.example.com/oauth2redirect/example-provider

小結

RFC 8252 主要在討論 OAuth2 在 Native App 上要怎麼做授權,但因 OpenID Connect 是建構在 OAuth2 上的,所以本 RFC 也是適用的。

另外,類似的 Single Page App 並不在此討論範圍,而是另一個 RFC OAuth 2.0 for Browser-Based Apps 裡面定義。

參考資料