作者:許凱平 / 臺灣大學計算機及資訊網路中心作業管理組副組長
雖然單一簽入的技術減輕了大家的負擔,使用者只要記一組帳號密碼,應用系統管理者不用管帳號,工程師也少了撰寫帳號系統的工作;但是如果大家不了解裡面的關鍵技術,沒有完整實作各種安全機制,未來還是有可能發生漏洞,所以實在不能不謹慎從事。本文將以實作觀點介紹WS-Federation[1]的相關技術,尤其是安全的部分。
前言
在資訊世界中,身分識別聯盟(Federated Identity,)[2]是一種將個人在不同的資訊系統的電子識別(帳號)加以連結的技術。在這個聯盟中各個角色的互動,形成一個信任的體系。單一簽入(Single sign-on) [3]扮演提供認證服務的腳色,並且維持跨系統的可操作性,讓使用者通過某一個資訊系統的驗證後,便可以藉著該系統發放的證書,使用其他加入聯盟的資訊系統。
以正式的詞彙來說,身分識別提供者(Identity provider, IdP)[4]負責對使用者進行身分驗證,並根據使用者的屬性及其將使用的資訊系統(Relying Party, RP)[5],進行一連串的運算後發行通行文件(Secure Token)[13]。RP 收到通行文件驗證無誤後,接著以該識別對應的使用者身分登入該資訊系統提供服務。
WS-Federation (Web Services Federation, WS-Fed) 是由一些資訊公司(Microsoft, IBM 等等)所發展的身分識別聯盟規格。作為 Web Service Security[6] 框架的一部份,WS-Federation 提供了不同安全領域交換身分、屬性以及認證資訊的機制與文件格式。
本文以WS-Federation 的實作,Microsoft Active Directory Federation Services (ADFS)[7]為例,說明如何以Passive requestor profile protocol[8] 進行身分識別聯盟。在這個協定中,用戶端並不需要為了單一簽入額外安裝程式,只要有網頁瀏覽器即可(要開啟cookie功能並允許JavaScript執行)。
預先知識
以下假設讀者已經大致上了解XML、HTML/CSS/JavaScript、HTTP Cookie、HTTP(S) Protocol (Redirect 的概念) 與URI(URL) 等知識。
締結同盟
要形成身分識別聯盟,首先要建立的是RP與IdP的信任關係。要建立信任關係,首先要有一些共識,否則沒有辦法合作。例如ADFS 預設的Web SSO 存留期為 480分鐘 (Session Duration),但是IIS預設為30分鐘。這是一個廣域設定,也就是說登入後,除非使用者特意登出,否則8個小時內就毋須再次登入。因為ADFS無法為單一RP設定較短的時間,所以只能從RP用一些特殊技巧才能做到較短的Session Duration。
另一個共識就是RP的callback 網址(被動端點)必須是走HTTPS協定,而伺服器憑證也必須是被信任的憑證機構有效簽署的憑證。一定要走HTTPS的原因是為了保護認證資訊不被攔截竄改;不建議使用自簽憑證的原因是,除非所有使用者的上網設備都裝上這張自簽憑證,否則在送回認證結果的時候就會被瀏覽器擋住。
接下來是認證結果的內容部分。普遍的做法是將登入者的電子郵件或學號等資訊當成名稱識別碼(NameIdentifier)送回。另外也可以附帶送一些屬性資料,例如服務單位與系所代碼等等,以下為系所代碼屬性(dptCode)與名稱識別碼的文件片段。
如果RP使用開發語言的是PHP,可以考慮使用SimpleSAMLphp[14],如果使用的是ASP.NET,則可以安裝WIF,使用WIF Federation Utility將應用設定為加入聯盟。如果不想使用這些框架的話,基本上RP只要能夠驗證XML Signature,剖析 XML取出需要的屬性就可以了。
簽入與重新導向
簽入的方式分成IdP起始或RP起始,前者常見於入口網站,使用者登入後再顯示他可以使用的RP,另一種是先連到RP的網站,使用者按登入後再將瀏覽器導向到IdP,RP製作重新導向的網址附帶的參數如下:
如果同一個安全領域有多個應用,可以將wtrealm跟wctx組合運用,不用每次開發一個應用就註冊一次。例如一個開發團隊承包一個組織(ex. orgx)的多個應用(ws1,ws2),就可以先註冊一個共用的wtrealm (xx.org),設定界接的入口(portal),每個網站在導向到IdP 的時候,再附加不同的wctx(ws1,ws2)。Portal 取得IdP回送的wctx,就可以再導向到ws1 或 ws2,示意圖如下。
圖一 wtrealm跟wctx組合運用
認證文件的製作
IdP在使用者輸入正確的帳號與密碼後,根據RP識別碼(wtrealm)找出這個RP在締結同盟時的設定要回應的資料。這些資料會以SAML [10]的格式打包,然後以IdP的私鑰簽章(XML Signature[11])再以Request Security Token Response, RSTR[12]的格式再打包送回給使用者的瀏覽器轉交RP。
圖二 Request Security Token Response
回應的處理
從瀏覽器轉交的資料以POST的方式送到RP的端點,wctx是RP重新導向給IdP所附的內容,wresult 內置的就是RSTR。
RSTR的子元素說明如下
● Lifetime:RSTR 的生命週期
o Created: RSTR 創建的時間,要注意時區。
o Expires: RSTR 到期的時間,一般是 Created 後一個小時。
● AppliesTo/EndpointReference/Address
o RP 的端點網址,RP 必須檢查適用對象是否為自己
● RequstedSecurityToken (RST)
o SAML Assertion Secure Token (ST)
● TokenType: SAML:1.0:assertion
o 說明 ST 遵循的標準(SAML)與版本(1.0)
RST的內容
● Conditions 這份聲明適用的條件
o 時間(NotBefore/NotOnOrAfter) ← RP 必須檢查是否有效
o 對象(Audience) ← RP必須檢查是否是發放給自己的
● AuthenticationStatement
o Subject 主體(證書持有人)的名稱識別碼(NameIdentifier)
● Signature ← RP 必須以IdP的憑證驗章
結語
一般而言,RP只要有驗電子簽章、檢查證書發放對象是否為自己這個應用以及是否在有效期間,就可以防止重送或竄改的攻擊。另外不論是RP或是IdP,都要隨時注意安全性議題,隨時幫自己的構建安裝修補程式,否則駭客還是有可能從其他軟體瑕疵攻入。孟子有言:「徒善不足以為政,徒法不足以自行。」初心再好,制度設計再怎麼完善,如果沒有貫徹執行的能力,資訊安全終究只是鏡花水月。我們也只能如希臘神話中的西西弗斯,雖然知道大石終將墜落,但也只能一次次地推著石頭上山,努力延後滑落時間,控制滑落時不要造成太大的損傷。
參考資料
[1] Web Services Federation Language (WS-Federation) Version 1.2
http://docs.oasis-open.org/wsfed/federation/v1.2/ws-federation.html
[2] Federated identity
https://en.wikipedia.org/wiki/Federated_identity
[3] Single sign-on
https://en.wikipedia.org/wiki/Single_sign-on
[4] Identity provider
https://en.wikipedia.org/wiki/Identity_provider
[5] Relying Party
https://en.wikipedia.org/wiki/Relying_party
[6] WS-Security
https://en.wikipedia.org/wiki/WS-Security
[7] Active Directory Federation Services, MSDN
https://msdn.microsoft.com/en-us/library/bb897402.aspx
[8] WS-Federation: Passive Requestor Profile
http://goo.gl/T5mhyL
[9] Introduction to Active Directory Federation Services, Keith Brown
https://goo.gl/b0GdKT
[10] Security Assertion Markup Language
https://en.wikipedia.org/wiki/Security_Assertion_Markup_Language
[11] XML簽章, 陳振寰
http://www.cc.ntu.edu.tw/chinese/epaper/0007/20081220_7007.htm
[12] Security Token Service Endpoint
https://msdn.microsoft.com/en-us/library/windows/desktop/ee652302.aspx
[13] Security token service
https://en.wikipedia.org/wiki/Security_token_service
[14] SimpleSAMLphp
https://simplesamlphp.org/
[15] Windows Identity Foundation
https://msdn.microsoft.com/zh-tw/library/hh377151(v=vs.110).aspx