iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0
Software Development

從登入到授權-現代軟體的身分架構指南系列 第 5

Day 05|SSO : 一次登入,通行所有系統

  • 分享至 

  • xImage
  •  

前言

過去三天,我們一直在討論「單一系統」要怎麼驗證使用者身份、怎麼維持登入狀態——從最基礎的 Basic Auth、Digest Auth、API Key、Session-based 登入,到另一個陣營的 Bearer Token、JWT、Access Token 與 Refresh Token。這些機制解決的都是同一個系統內部的問題。

但現實中,一個使用者要面對的往往不是一個系統,而是好幾十個系統,例如公司內部可能同時用 Gmail、Google Drive、Slack……如果每個系統都要求使用者各自登入一次,不但使用者要記住一大堆密碼,IT 團隊也要在每個系統各自管理帳號、各自處理忘記密碼的請求。這就是今天要談的 SSO(Single Sign-On,單一登入) 要解決的問題。

今天內容涵蓋:

  1. SSO 解決的問題
  2. SSO 核心角色:IdP 與 SP
  3. SSO 的運作流程
  4. 常見協定:SAML 與 OIDC
  5. SSO 的風險與相關概念辨析

一、SSO 解決的問題

沒有 SSO 的時候,使用者面對的是這樣的情境:每換一個系統就要重新輸入一次帳密。為了記得住,很多人會做兩件不安全的事——把密碼設得很簡單,或者好幾個系統共用同一組密碼。只要其中一個系統的密碼資料庫被攻破,攻擊者就能拿同一組帳密去嘗試登入其他系統。

而 IT 團隊要面對的,是另一種困擾:使用者一多,忘記密碼、重設密碼的請求就會變多,每個系統都要各自維護使用者帳號,也要處理權限的開通與收回;員工離職時則得一個系統接一個系統手動停用帳號,一旦漏了哪個系統沒做,就會留下資安風險。

SSO 想做的事很單純:讓使用者只登入一次,就能存取多個彼此獨立、互相信任的應用程式或系統,不用每個系統都重新輸入一次帳密。

這裡先定位一下 SSO 本身是什麼:嚴格說起來,SSO 只是一種使用者體驗模式(UX pattern),描述的是「登入一次、多處通行」這個結果,本身不是一種驗證方法;實際負責驗證身份的,是後面會介紹的 SAML、OIDC 這類身份協定。

簡單說,SSO 可以看成 IAM 裡的一個功能。SSO 解決的是「使用者不用每個系統都登入一次」的問題;IAM 管的範圍更大,還包含帳號怎麼建立、離職時怎麼停用、權限怎麼分配、誰能存取哪些資源,以及這些行為要怎麼被稽核。

也因為這樣,SSO 的價值不只是讓使用者少輸入幾次密碼,而是讓組織可以把登入政策集中管理。例如:要不要強制 MFA、密碼規則怎麼設計、員工離職時要不要停用帳號、哪些系統可以被哪些人存取,這些都可以集中在 IdP 或 IAM 系統裡處理,而不是散落在每一個應用程式裡。


二、SSO 核心角色 - IdP 與 SP

SSO 要運作,需要先在角色之間建立信任關係,主要有兩個角色:

  • IdP(Identity Provider,身份提供者):專門負責「儲存、管理、驗證使用者身份」的角色,可以想成一份實名制的「賓客名單」——只不過它管的不是某場活動,而是使用者在各種雲端服務上的身份。常見的 IdP 有 Okta、Google Workspace、Microsoft Entra ID,或是企業自己架設的驗證伺服器。使用者的帳密只交給 IdP 一個地方處理,其他系統都不會直接接觸到帳密本身。現代 IdP 通常不只驗證帳密,也會整合 MFA、社交登入、企業目錄、使用者資料管理,並發出 SAML Assertion、ID Token、Access Token、Refresh Token 等驗證或授權結果。
  • SP(Service Provider,服務提供者):實際要存取的應用程式,例如 Gmail、Salesforce、公司內部系統。SP 本身不驗證使用者的帳密,而是把這件事交給 IdP,自己只負責相信 IdP 給的驗證結果。在 OIDC 的語境裡,SP 也常被稱為 Relying Party,意思是「依賴 IdP 驗證結果的一方」。

https://ithelp.ithome.com.tw/upload/images/20260909/20181928HnngEIknqb.png

SP 之所以敢把驗證這件事交給 IdP,是因為兩者事先建立了信任關係。以 SAML 為例,IdP 和 SP 通常會交換 metadata,裡面包含 Entity ID、憑證/公鑰、登入與回傳用的 endpoint URL 等資訊。SP 之後收到 IdP 傳來的 Assertion 時,就可以用事先信任的公鑰驗證簽章,確認這份結果真的是由可信任的 IdP 發出,而且沒有被中途竄改。


三、SSO 的運作流程

以「使用者登入一次,接著依序存取應用系統 A、B、C」為例:

https://ithelp.ithome.com.tw/upload/images/20260909/20181928zYMxf4rydz.png

流程如下:

  1. 使用者第一次登入 IdP,驗證通過後,IdP 在使用者瀏覽器上設定 SSO Cookie,同時在背後建立一份全域 Session,之後每次就用這份 Session 來驗證使用者是否已登入。
  2. 使用者接著存取應用系統 A,應用系統 A 發現使用者還沒有通過驗證,把使用者導向 IdP。
  3. IdP 看到使用者已經有全域 Session,不用再要求重新輸入帳密,直接把「已驗證、身分資訊」回傳給應用系統 A,讓使用者進入。
  4. 使用者接著存取應用系統 B,應用系統 B 一樣去跟 IdP 確認 Session 是否有效,IdP 確認後回覆「已確認,無需重新登入」,使用者就直接進入應用系統 B。
  5. 之後存取應用系統 C 也是同樣道理,只要全域 Session 還有效,就能直接存取,不用再登入一次。

這裡要特別釐清「全域 Session」和 IdP 的關係。所謂全域 Session,指的是 IdP 自己維護的登入狀態。使用者第一次在 IdP 登入成功後,IdP 會透過 Session / Cookie 記住「這個使用者已經登入過」。之後其他 SP 把使用者導回 IdP 時,IdP 就可以根據這份登入狀態,判斷是否需要再次要求使用者輸入帳密。

但這不代表所有 SP 都共用同一份 Session。每個 SP 收到 IdP 回傳的驗證結果後,通常還是會在自己的系統裡建立一份本地 Session,或簽發自己的 Token。之後使用者操作這個 SP 時,就靠 SP 自己的登入狀態維持使用者身份。

所以 SSO 的重點不是「所有系統共用同一份 Session」,而是「所有 SP 都信任同一個 IdP」。IdP 負責確認使用者是否已經登入;SP 則根據 IdP 回傳的驗證結果,決定是否讓使用者進入自己的系統。至於 IdP 回傳給 SP 的「驗證結果」具體長什麼樣子,就是下一節要介紹的兩種常見協定的差異所在。


四、常見協定 - SAML 與 OIDC

IdP 驗證完使用者身份之後,要用什麼格式把「這個人是誰、驗證通過了」這件事告訴 SP,目前最常見的兩套就是 SAMLOIDC。簡單先定位一下這兩套到底是什麼:SAML 是一套用 XML 描述「驗證聲明」的開放標準協定,歷史較久;OIDC 則是建立在 OAuth 2.0 這套授權框架之上、專門處理身份驗證的協定。

不過這篇會把重點放在 SSO 的整體概念與 SAML 的基本流程,OIDC 只先放在比較表裡定位,後面等 OAuth 2.0 講完後會再獨立開一篇細講。

兩套本質上都是在定義「驗證完之後,要用什麼格式跟 SP 溝通」,以存取 Salesforce(用 SAML)與 Gmail(用 OIDC)為例:

https://ithelp.ithome.com.tw/upload/images/20260909/20181928DyyG8Zux0W.png

流程如下:

  1. 使用者存取 Salesforce,Salesforce 發現使用者尚未登入,將使用者重新導向到 SAML IdP。
  2. SAML IdP 驗證使用者身份。
  3. 驗證通過後,SAML IdP 產生一份 SAML Assertion(XML),回傳給 Salesforce。
  4. Salesforce 確認 Assertion 有效,讓使用者以「身分已確認」的狀態進入應用程式。
  5. 使用者接著存取 Gmail,Gmail 發現使用者尚未登入,將使用者重新導向到 OIDC IdP。
  6. OIDC IdP 驗證使用者身份。
  7. 驗證通過後,OIDC IdP 產生一個 ID Token(JWT),回傳給 Gmail。
  8. Gmail 確認 ID Token 有效,讓使用者以「身分已確認」的狀態進入應用程式。

存取 Salesforce 這類用 SAML 整合的應用程式,走的是步驟 1~4;存取 Gmail 這類用 OIDC 整合的應用程式,走的是步驟 5~8。兩者最後換回來的東西不同(SAML Assertion 與 ID Token),但都是「驗證結果」的不同表達格式,整理如下:

比較項目 SAML OIDC
資料格式 XML JSON(JWT)
建立在什麼基礎上 獨立的協定 OAuth 2.0 之上
常見場景 企業內部系統整合 現代 Web / 行動裝置、第三方登入
驗證結果 SAML Assertion(附簽名) ID Token(JWT,附簽名)

看完整體差異後,這裡先深入歷史比較久的 SAML;OIDC 建立在 OAuth 2.0 之上,等之後把 OAuth 2.0 說明完,會再回來深入說明這部分。

SAML(Security Assertion Markup Language)

SAML 用 XML 格式描述一份「聲明(Assertion)」,裡面記錄了使用者身份、驗證時間等資訊,並附上簽名,歷史較久,常見於企業內部系統(例如 Salesforce)的 SSO 整合。目前的主流版本是 SAML 2.0(2005 年推出,整合了先前幾個版本),下面內容都是以 SAML 2.0 為準;較舊的系統可能還保留 SAML 1.1 以維持向下相容,但新系統基本不會再採用。一份 SAML Assertion 主要包含:

  • Issuer:簽發這份 Assertion 的 IdP 是誰。
  • Subject:這份 Assertion 是關於哪一位使用者(通常是一個 Email 或內部帳號 ID)。
  • Conditions:這份 Assertion 的有效範圍,例如有效期間(NotBefore/NotOnOrAfter)、限定給哪個 SP 使用(AudienceRestriction)。
  • AuthnStatement:記錄使用者是什麼時候、用什麼方式完成驗證的(例如密碼、MFA)。
  • AttributeStatement(可選):使用者的其他屬性,例如 Email、部門、角色,SP 可以拿這些屬性做進一步的權限判斷。

簡化過的 Assertion 大致長這樣:

<saml:Assertion>
  <saml:Issuer>https://idp.example.com</saml:Issuer>
  <saml:Subject>
    <saml:NameID>user@example.com</saml:NameID>
  </saml:Subject>
  <saml:AuthnStatement AuthnInstant="2026-08-26T06:00:00Z" />
  <saml:AttributeStatement>
    <saml:Attribute Name="role">
      <saml:AttributeValue>admin</saml:AttributeValue>
    </saml:Attribute>
  </saml:AttributeStatement>
</saml:Assertion>

實務上最常見的是用 SAML Assertion 來表達「這個使用者已經完成身份驗證」,同時也可能夾帶 Email、部門、角色等屬性,讓 SP 後續建立帳號或判斷權限。

實際傳輸時,SAML 定義了兩種常見的Binding(傳輸方式):

  • HTTP Redirect:適合傳送比較短的訊息(例如 SP 發給 IdP 的 AuthnRequest,也就是「請幫我驗證這個人」的請求),直接放進 URL 查詢參數裡重新導向。
  • HTTP POST:適合傳送比較長的訊息(例如 IdP 回傳給 SP 的 Assertion 本身,內容通常太長放不進 URL),改用一個自動送出的表單,把資料放在請求本文裡 POST 過去。

另外,SAML 流程裡常會看到一個參數叫做 RelayState。它可以想成「登入前使用者原本想去哪裡」的暫存資訊。當使用者被 SP 導向 IdP 登入時,SP 可以把原本要前往的頁面或狀態放進 RelayState;等 IdP 驗證完成、把使用者導回 SP 後,SP 就能根據 RelayState 把使用者帶回原本想看的頁面。

除了改善使用者體驗,RelayState 也可以用來協助確認這次回來的登入結果,是不是對應到先前由 SP 發起的那次請求,避免流程被混淆或濫用。

流程還可以再分成兩種發起方式:

  • SP-initiated:使用者先直接存取 SP,SP 發現使用者未登入,主動產生一個 AuthnRequest(即「請幫我驗證這個人」的請求) 導向 IdP,也就是前面第三節介紹過的流程。
  • IdP-initiated:使用者先登入 IdP 的入口網站(例如企業的應用程式入口首頁),直接點選某個應用程式的圖示,IdP 主動把 Assertion 送給 SP,中間沒有先發出 AuthnRequest。這種方式比較方便,但安全性稍低——因為沒有 SP 主動發出的請求可以互相對應,SP 只能單方面信任 IdP 送來的 Assertion,比較難確認這份 Assertion 是不是專門為這次存取產生、而不是被別人攔截後拿來重複使用;實作上需要額外檢查 Assertion 的時效性與指定的目標 SP,避免遭到重放攻擊。

風險:因為 Assertion 裡帶有使用者身份等敏感資訊,SAML 規範要求 Assertion 必須簽名,防止內容被竄改;如果內容本身也需要保密(不想讓中間的瀏覽器或代理看到),還可以進一步加密整份 Assertion。

OIDC(OpenID Connect)

OIDC 建立在 OAuth 2.0 這個授權框架上,IdP 驗證完之後會回傳一個 ID Token——也就是一種 JWT,裡面用 subissexp 等欄位描述使用者身份,SP 驗證簽名就能相信內容。常見於現代 Web、行動裝置的登入整合(例如「使用 Google 帳號登入」)。

這篇先知道它和 SAML 一樣,都是 IdP 用來把「使用者已經驗證通過」這件事告訴 SP 的方式就好。至於 OIDC 為什麼建立在 OAuth 2.0 之上、Authorization Code Flow 怎麼換回 ID Token、ID Token 和 Access Token 又差在哪裡,後面會獨立開一篇再完整說明。

除了 SAML、OIDC,企業內部網路環境也常見像 Kerberos 這種以票證(Ticket)為基礎的協定,之後再深入展開。

這裡也順便澄清一個常被混淆的概念:LDAP(Lightweight Directory Access Protocol) 跟 SAML、OIDC 常被放在一起講,但它其實不是同一層次的東西:

  • LDAP——查詢、核對「帳號密碼」的協定:LDAP 是一種用來存取「目錄服務(Directory Service)」的協定,功能類似資料庫查詢,常見的目錄服務有 Active Directory。使用者輸入帳密要登入時,IdP 通常會把這組帳密透過 LDAP,去問後端的目錄服務:「這個帳號存在嗎?密碼對不對?」。LDAP 只負責這一步「核對帳密」,完全不會接觸到 SP,跟 SAML、OIDC 做的是兩件不相關的事。
  • SAML/OIDC——把「驗證結果」傳給 SP 的協定:LDAP 核對帳密只是 IdP 內部的其中一步,等 IdP 確定使用者身份沒問題(不管背後是查 LDAP、比密碼、還是走 MFA),才輪到 SAML、OIDC 上場:它們負責把「這個人已經驗證通過了」這件事,包成 SAML Assertion 或 OIDC 的 ID Token,傳給 SP。

換句話說,LDAP 發生在 IdP 內部(拿來查帳密資料),SAML/OIDC 發生在 IdP 跟 SP 之間(拿來傳送驗證結果)。同一次登入流程裡,兩種可能都會用到(例如企業內部的 IdP 背後接一個 LDAP 目錄來存放帳密),但做的事完全不同層次,這裡先點出差異,其他細節之後再另外深入。


五、SSO 的風險與相關概念辨析

風險:

  • 單一登入等於單一風險點:一旦 IdP 的帳密被攻破,攻擊者能直接存取所有信任這個 IdP 的應用程式,等於拿到一組能開所有門的鑰匙。所以 IdP 這一次登入的安全性要求,遠比單一系統的登入更高,通常會強制搭配 Day02 介紹過的 MFA
  • IdP 掛掉,所有系統都連帶受影響:因為每個應用程式都依賴 IdP 才能完成驗證,IdP 本身的穩定性變得非常關鍵。

相關概念辨析(常被搞混):

  • SSO vs 聯合身份管理(Federated Identity Management,FIM):FIM 是更大的架構,讓不同組織、不同廠商之間互相信任並共享身份;SSO 通常侷限在同一個組織或同一個身份供應商底下的一次登入,可以看成是 FIM 底下的一種具體功能。
  • SSO vs Same Sign-On:名字很像,但概念不同。Same Sign-On 只是把使用者的帳密同步、記住(類似密碼管理器),使用者每個系統還是各自要登入一次,只是不用手動輸入;SSO 則是真正只驗證一次,之後其他系統都不用再登入。
  • SSO vs MFA:兩者不是互相取代的關係,而是互補:SSO 讓「這一次登入」能通行多個系統,MFA 則負責把「這一次登入」的安全性做好,實務上通常會一起用。

小結

SSO 想解決的問題,是讓使用者完成一次身份驗證後,就能進入多個彼此信任的應用程式,不必在每個系統重複輸入帳密。不過,SSO 本身描述的是「一次登入、多處通行」的使用體驗,真正讓這件事成立的,是 IdP 與 SP 之間事先建立的信任關係,以及 SAML、OIDC 等協定所傳遞的驗證結果。

在整個流程中,IdP 負責驗證使用者並維護全域登入狀態;SP 不直接處理使用者的帳密,而是驗證 IdP 回傳的 Assertion 或 ID Token,再建立自己的本地 Session。也就是說,SSO 並不是讓所有系統共用同一份 Session,而是讓多個 SP 都信任同一個 IdP。

以下整理的重點:

  1. SSO 是一種登入體驗,不是一套獨立的驗證協定:它描述的是使用者只需要登入一次,後續系統則透過共同信任的 IdP 確認身份。
  2. IdP 與 SP 的信任關係是 SSO 的核心:IdP 集中處理身份驗證、MFA 與登入政策,SP 則驗證 IdP 發出的結果,並自行維護應用程式內的登入狀態。
  3. SAML 與 OIDC 負責傳遞驗證結果:SAML 使用 XML 格式的 Assertion,常見於企業系統;OIDC 建立在 OAuth 2.0 之上,透過 ID Token 傳遞身份資訊,較常用於現代 Web 與行動應用程式。

不過,IdP 要完成身份驗證,背後仍然需要一個地方保存帳號、群組與組織資料,也需要一套方式證明使用者身份。下一篇會進一步介紹企業環境中常見的 LDAPKerberos,看看它們如何分別負責目錄查詢與票證驗證,又為什麼至今仍是 Active Directory 的重要基礎。


參考資源


上一篇
Day 04|拆解 Token-Based Auth:Bearer、JWT、Access Token 與 Refresh Token
下一篇
Day 06|LDAP 與 Kerberos:企業目錄服務與票證驗證
系列文
從登入到授權-現代軟體的身分架構指南9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言