WCF傳輸安全(Transfer Security)的基本概念和原理:認證(Authentication)[上篇]
對於任何一個企業級應用來說,安全(Security)都是一個不可回避的話題。如何識別用戶的身份?如何將用戶可執行的操作和可訪問的資源限製在其允許的權限範圍之內?如何記錄用戶行為,讓相應的操作都有據可查?這些都是應用的安全機製或者安全框架需要考慮的典型問題,它們分別對應著三個安全行為:認證(Authentication)、授權(Authorization)和審核(Auditing)。
除了這些典型的安全問題,對於一個以消息作為通信手段的分布式應用,還需要考慮消息的保護(Message Protection)問題。具體來講,消息保護機製主要包括簽名(Signature)和加密(Encryption)。簽名確保消息的一致性(Message Integrity),即保證消息在最初發送者和最終接收者之間沒有被第三方篡改。而加密確保消息的機密性(Message Confidentiality),即保證消息的內容僅僅對發送者期望的接收者可見。
作為Windows平台下最完備的分布式通信平台,WCF具有一套強大的、完整的的可擴展安全體係,對上述的安全問題提供有效的支持。由於安全體係在整個WCF框架體係中具有極其重大的分量,在接下來的係列文章中,我將深入探討這一塊在我之前的文章中一直不曾觸碰的境地。由於安全體係在整個WCF框架體係中具有極其重大的分量,我特意將其分成兩個部分:傳輸安全(主要涉及對認證、消息一致性和消息機密性的實現)和授權與審核。
WCF是一個以消息作為通信手段的分布式編程平台,使我們可以將某些可複用的功能以服務的方式進行定義,並最終部署於分布式網絡環境中的某個節點,供潛在的服務消費者調用。服務和調用服務的客戶端可以同時存在一個相同的網絡,也可以跨越不同的網絡,甚至需要借助於Internet。網絡的不確定性為分布式應用帶來了一係列安全隱患,在正式投入介紹WCF的傳輸安全之前,我們先來介紹一下這些安全隱患。
一、分布式應用中的傳輸安全隱患
我們可以將WCF看成是一個消息處理框架,整個框架大體分成兩個部分,客戶端和服務端。客戶端負責請求消息的發送和回複消息的接收,而服務端則負責請求消息的接收和回複消息的發送。WCF隻能控製對消息發送前和接收後的處理,而對發送後到接收前這一段消息傳輸過程卻無能為力。而正是消息傳輸的網絡不能提供足夠的安全保障,會帶入如下一些典型的安全隱患:
- 消息的篡改:傳輸中的消息被某些網絡攔截工具捕獲,並被惡意篡改後轉發給消息接收者。消息接收者接收會做出錯誤的操作或者返回給客戶端錯誤的結果。比如說客戶端調用服務進行銀行轉賬,該請求會包含轉出和轉入銀行帳號和轉入金額,如果網絡黑客截獲該消息後改變了相應的賬號或者金額數據,並將篡改後的請求進行轉發。如何服務端將接收到的消息當成是正常的轉賬請求,後果可想而知;
- 敏感信息的泄漏:消息往往中包含一些敏感的信息,比如信用卡號、身份證號等,如何這些消息以明文的方式在網絡中被傳輸,被網絡攔截工具捕獲後很自然地會被惡意的黑客看到;
- 釣魚攻擊(Phishing Attack):針對服務A的請求被惡意重新定位到另一個服務B,以執行一些損害訪問者利益的操作,或者竊取訪問者相關的一些敏感信息。同樣以網銀服務為例,用戶調用網銀認證服務並提供自己的帳號和密碼進行登錄。如果訪問者在進行服務調用之前沒有驗證自己試圖訪問服務的真實身份,貿然地將自己的網銀帳號的密碼作為請求發送出去,如果該請求被定位到一個黑客或者流氓軟件廠商偽造的服務,它將有可以直接獲取到你提供的帳號和密碼信息;
- 重放攻擊(Replay Attack):黑客利用網絡攔截工具捕獲針對某個服務的訪問請求,然後對該請求進行複製並以一個非常高的頻率對目標服務發起調用。如果服務方將每一個接收到的消息都當成是來自正常訪問者的請求,來者不拒,最終將會耗盡服務端的可用資源並崩潰。
上麵給出了分布式網絡應用中由於網絡環境的不確定性導致的幾個比較典型的安全隱患,實際上,由於網絡協議本身並不提供足夠的安全保障,我們還會遇到其它很多網絡完全問題。網絡安全問題在Internet環境下尤為突出,Internet從其產生以來在一段不算長的時間內得到如此迅勐發展,以致改變了我們生活、學習以致思維方式,其中一個主要的技術因素在於它建立在一個“簡單”的HTTP協議之上。但是,也正是HTTP的簡單性,導致其自身並不能提供足夠的安全保障機製。總之,為了彌補網絡協議本身對安全保障的局限,我們往往不得不在應用級別重建安全體係。
但是,安全是一個相對“高級”的話題,構建一個適合具體應用要求的安全體係對應用的開發和架構人員具有較高的要求。對於一般的中小規模的分布式應用,投入到安全架構方麵的成本完全有可能超過實現業務應用模塊的總和。而且,花大力氣構建的安全體係可能並不會你想象的那麼安全。所以,將安全的實現完全下方到具體的應用也是不太現實的。
既然在網絡通信層麵不能提供足夠的安全保障,而在應用層麵去實現安全保障也不太現實,那麼我們隻能將整個安全保障體係構建於兩者之間,我們可以的解決方案姑且稱為平台級別或者框架級別的安全保障體係。
作為分布式開發平台的WCF為我們實現了一個功能齊全的、可擴展的安全架構體係,能夠滿足絕大部分分布式應用場景的安全需求。作為建立在WCF上的分布式應用的架構人員,隻需要根據自身的場景進行相應的配置即可。換言之,WCF為每一個具體的安全問題提供了一係列現成的實現方案,安全架構人員隻需要根據應用所麵臨的具體需求對每一個具體安全問題選擇一個最適合的方案,然後將它們組合在一起就是最終的安全保障的實現方案。接下來,我們來簡單地介紹一下WCF傳輸安全體係如何解決上述的這些網絡安全隱患。
在本篇文章的一開始我們就提到了,WCF的傳輸安全旨在解決三個典型的安全問題,即認證、消息一致性和消息機密性,我們下來討論一下什麼是認證,如何實現認證。
二、認證(Authentication)
在冷兵器時代,為了抵禦敵方入侵取保城池安全,需要修築堅固的城牆,挖掘較深的護城河。實際上,城池二字原本的含義就是指代的城牆和護城河。對於一些兵家必爭的軍事重鎮,往往具有不止一道堅城,比較典型防禦體係就是修築內城和外城。這樣防線設置確保你在外層防線被突破之後依然退回到第二道防線進行繼續抵抗。
對於當代戰爭,雖然高城深池起不了任何的防禦作用,但是這樣設置多道安全屏障的防禦體係的理念依然是目前構建網絡安全體係的指導方針。以一個分布式的Web應用為例,我們可以在Web服務器和應用服務器設置防火牆。前者確保Web服務器的安全,使第一道防線。即時黑客突破該防線,依然可以保障核心業務的安全,因為這樣的邏輯處理都是一服務的形式部署在應用服務器上。
對於具體的應用來說,在很大程度上講,安全的含義就是讓某個人做他可以做的事情。應用為用戶提供對某項功能的實現,或者實現對某種資源的存取,但是操作的執行和資源的訪問必須依賴於用戶自身的權限。也就是說,我們需要確保在用戶既定權限範圍內提供為該用戶提供服務,這就是我們所說的授權(Authorization)或者存取控製(Access Control)。
但是,對用戶進行合理授權的一個前提是當前用戶身份已經被確認,這種對訪問者身份識別和鑒定的行為被稱為認證(Authentication)。認證往往是應用或者服務安全體係的第一道屏障,如果沒有了這道屏障,後續的安全防線將形同虛設。認證幫助我們確認“誰在敲打我的門?”。應用或者服務的訪問者以一個它申明的身份叩響第一道城門,看門人隻有在成功確定對方身份無誤之後方能為其開啟方便之門,否則直接將其掃地出門。
如果要給認證下一個定義,我個人的傾向這樣的定義:認證是確定被認證方的真實身份和他或她申明(Claim)的身份是否相符的行為。認證方需要被認證方提供相應的身份證明材料,以鑒定本身的身份是否與聲稱的身份相符。在計算機的語言中,這裏的身份證明有一個專有的名稱,即“憑證(Credential)”,或者用戶憑證(User Credential)、認證憑證(Authentication Credential)。
三、用戶憑證(User Credential)
最好的設計就是能夠盡可能的模擬現實。對於安全認證來說,在現實生活中有無數現成的例子。比如我對一個不認識的人說:“我是張三”,對方如何才能相信我真的是張三而非李四呢?雖然我們未必全都是有身份的人,但無疑我們都是有身份證的人,身份證可以證明我們的真實身份。而這裏的身份證就是一種典型的用戶憑證。
認證方能夠根據本認證方提供的身份證識別對方的真實身份,必須滿足三個條件:其一,被認證人聲稱是身份證上注明的那個人;其二,身份證的持有者就是身份證的擁有者;其三,身份證本身是合法有效的,即使通過公安機關頒發的,而不是通過撥打“辦證”電話辦理的。第一個問題一般不是問題,因為對於一個神經稍微正常的人來說,他不會拿著李四的身份證去證明自己是張三;第二個問題可以根據身份證上麵的照片來判斷;第三個問題就依賴於身份證本身的防偽標識和認證方的鑒別能力了。
上述的三個條件本質上也反映了,能夠基於用戶憑證的認證過程中憑證本身應該具有的屬性,以及憑證和本認證人的關係,即:憑證與聲明的一致性,被認證人對憑證的擁有性,以及憑證的合法性。為了簡單,我們不妨簡稱為用戶憑證的三個屬性。用戶憑證的類型決定了認證的方式,WCF支持一係列不同類型的用戶憑證,以滿足不同認證需求。接下來,我們按照上述的這三點來簡單介紹幾種使用比較普遍的用戶憑證以及相應的認證方式。
用戶名/密碼
我們最常使用的認證方式莫過於采用驗證用戶名和密碼的形式,以致於我們提到身份驗證,很多人會想到密碼。最為常用的憑證類型,用戶名/密碼憑證由兩個要素構成,即用戶名和密碼。我們不妨通過上麵我們講到的用戶憑證的三屬性來分析用戶名/密碼憑證。
前者表示被認證方聲明的身份(Identity),後者是持有人是憑證合法擁有者的證據。對於認證方來說,由於賬號對應的密碼屬於賬號擁有者的私密信息,如果被認證方能夠提供與他聲明身份相匹配的密碼,就能夠證明對方確實與他聲明的是同一個人。首先,用戶名代表身份(Identify),憑證與聲明的一致性意味著本認證方聲明的身份與用戶名一致;被認證人對憑證的擁有性通過密碼證明,密碼屬於絕對隱私信息,被認證人如果能夠提供與所聲明的身份相匹配的密碼,就能夠證明他是憑證的真正擁有者;由於用戶名/密碼憑證不屬於證書型憑證,不需要合法機構頒發,對於合法性則無從說起。
在采用用戶名/密碼認證方式的應用中,認證方一般具有所有用戶帳號和密碼的列表。當然,由於密碼對屬於持有人的決定隱私,原則上僅限於持有人本人知曉,其他人任何人(當然也包括認證方)不應該采用技術手段獲知該密碼。如果認證方維護者他負責認證的所有帳戶的用戶名和密碼的列表,本存儲的一般是原始密碼的哈希值以及進行哈希運算采用的Key。由於哈希算法是不可逆的,所以無法通過後哈希的值和相應的Key得到原始的值,從而確保了密碼的安全性。在進行認證的時候,隻需要根據用戶名找到相應的Key,然後利用該Key采用相同的算法對用戶提供的密碼進行哈希算法,最終將最終的運算結果和本地存儲的值進行比較即可驗證密碼的真偽。
雖然在我們進行項目開發的時候,我們也會選在對用戶注冊時提供的密碼進行加密存儲,這樣可以讓用戶忘記原來的密碼的時候,通過向認證方證明其真實身份的前提下,讓認證方通過通過解密返回其原來的密碼。對於密碼的加密存儲問題,無論是采用對稱加密還是非對稱加密,我們都可以通過相應的解密算法得到其原始密碼,所以從理論上講具有安全問題。不過,具體應用在選擇密碼存儲策略的時候,可以根據自身所需的安全級別以及是否需要返回原始密碼,選擇對原始密碼進行哈希或者加密。但是,無論如何對密碼進行明文存儲是不被允許的。
那麼WCF服務端對於客戶端提供的用戶名/密碼用戶憑證,應該采用怎樣的驗證手段呢?在基於用戶名/密碼的驗證規則方麵,WCF的安全框架體係為你提供了多種方案。個人覺得,最具有價值的采用基於ASP.NET Membership的認證。關於ASP.NET Membership認證,相信使用過ASP.NET 2.0以及之後版本的讀者應該不感到陌生。
我們還可以將客戶端提供的用戶名和密碼映射為Windows賬號和相應的密碼,這樣我們就可以采用Windows認證識別客戶端的真實身份。如果這兩種方式依然不能滿足你對於基於用戶名/密碼的認證需求,你可以自行定義認證實現,你隻需要創建一個繼承於System.IdentityModel.Selectors.UserNamePasswordValidator類型的類就可以。
Windows憑證
應該說就采用的頻率程度,集成Windows認證(IWA:Integrated Windows Authentication)是僅次於用戶名/密碼的認證方式。尤其是在基於Windows活動目錄(AD:Active Directory)的Intranet應用來說,Windows認證更是成為首選。微軟幾乎所有需要進行認證的產品或者開發平台都集成了Windows認證,比如IIS,SQL Server,ASP.NET等,當然,WCF也不可能例外。
Windows是實現單點登錄(SSO:Single Sign-On)最理想的方式。無論是采用域(Domain)模式還是工作組(Workgroup)模式,隻要你以Windows帳號和密碼登錄到某一台機器,你就會得到一個憑證。在當前會話超時之前,你就可以攜帶該Windows憑證,自動登錄到集成了Windows認證方式的所有應用,而無須頻繁地輸入相同的Windows帳號和密碼。如果登錄帳號不具有操作目標應用的權限,在一般情況下,你好可以通過重新輸入Windows帳號和相應的密碼(如果當前用戶具有多個Windows帳號)以另外一個身份(該身份具有對目標應用進行操作的訪問權限)對目標應用進行操作。
對於WCF的Windows與之類似,在不考慮模擬(Impersonation)和委托(Delegation)的情況下,WCF客戶端安全框架自動將客戶端應用進程的Windows憑證,作為調用服務的客戶段憑證發送給服務進行認證。此外,在編寫客戶端程序的時候,我們還可以通過指定Windows用戶名和密碼動態地創建Windows憑證,並將其作為客戶端憑證進行服務的調用。Windows憑證需要通過提供Window帳號和相匹配的密碼來獲取,從性質上也可以看成是用戶名/密碼憑證的變體,我們可以照用戶名/密碼憑證的方式來分析Windows憑證的三個屬性。
就其實現來說,Windows具有兩種不同的認證協議,即NTLM(NT LAN Manager)和Kerberos,分別作為工作組和域模式下的網絡認證協議。由於在具體的服務調用環境中,采用的Windows憑證實際上分別是NTML或者Kerberos票據。
在下篇中我們將會討論另一種重要的用戶憑證,即數字證書,以及由此引出的關於非對稱密碼學(或者公鑰密碼學)。下篇文章不僅僅會為你深入數字證書背後的原理,還會讓你對數字簽名和加密有一個深刻的了解。
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
最後更新:2017-10-27 14:34:27