天天看點

[WCF安全系列]服務憑證(Service Credential)與服務身份(Service Identity)一、服務憑證(Service Credential)二、服務身份(Service Identity)三、服務憑證協商

目錄: 一、服務憑證(Service Credential) 二、服務身份(Service Identity) 三、服務憑證協商(Service Credentials Negotiation)

認證就是通過對對方提供的憑證進行檢驗以确定對方身份的一個過程,從這個意義上講服務認證和用戶端認證并沒有本質的差別。但有服務認證确實有一點和用戶端認證不同:用戶端在對服務進行認證之前就預先确定了服務應當具有的身份。而在真正進行服務調用的時候,用戶端要求服務提供相應的憑證。而用戶端根據這個憑證和實作确定的身份進行比較,進而确定目前正在調用的服務正是自己希望調用的那個。

通過上面一節的介紹,我們已經知道了用戶端具有多種形式的憑證類型,但是服務憑證具有兩種典型的類型:Windows憑證和X.509證書。服務憑證的類型決定了認證方式,是以服務認證通過Windows認證或者對X.509證書的檢驗來實作。

Group)環境中,我們推薦使用基于證書的服務認證。

我們通常所說的“調用某個服務”實際上應該是“調用服務的某個終結點”,而服務身份實際上也應該是“終結點身份”。與此對應的,通過ServiceEndpoint對象表示的終結點的身份通過Address的Identity屬性來表示,而該屬性的類型就是本節着重介紹的EndpointIdentity。在深入介紹EndpointIdentity之前,我們不妨先來看看它的定義。

我們先來介紹一下SpnEndpointIdentity和UpnEndpointIdentity。這兩個EndpointIdentity是Windows認證下服務身份的兩種表現形式。前者被稱為服務主體名(SPN:Service Principal Name,以下簡稱SPN),另一種被稱為使用者主體名(UPN:User Principal Name,以下簡稱UPN)。

如果你對Kerberos有一定的了解,相信一定對SPN不會感到陌生。對于一個運作在域環境中某台機器上的服務,它能被通路它的用戶端認證的先決條件是:用戶端能夠唯一辨別該服務,而SPN就可以看作是這個辨別符。在預設的情況下,如果服務寄宿程序在機器帳号(或者系統帳号,比如LocalService, LocalSystem, or NetworkService等)下,服務身份通過SPN表示;如果執行服務寄宿程序的是一個域使用者帳戶,則采用UPN表示服務身份。WCF中的SPN和UPN的格式如下。如果用戶端預先指定SPN/UPN表示服務身份,它通過執行服務寄宿程序帳号對應的Windows憑證和SPN/UPN進行比較,從未确定服務運作在預先設定的機器或者某個域使用者帳号下。

如果采用X.509證書作為服務憑證,服務身份可以通過X509CertificateEndpointIdentity和RsaEndpointIdentity表示。而X509CertificateEndpointIdentity有具有兩種表現形式,既可以直接采用X.509證書中的指紋作為服務身份辨別,也可以采用為了存儲區中某個證書的引用來表示。而RsaEndpointIdentity則将X.509證書的RSA密鑰作為服務身份辨別。如果用戶端預先制定了相應的X509CertificateEndpointIdentity/RsaEndpointIdentity作為服務身份,它會通過将作為服務憑證的X.509證書與此進行比較進而确定服務是相應證書的真正擁有者。

而對于DnsEndpointIdentity,故名思義就是基于域名系統(DNS: Domain Name

System)的服務身份表現形式。如果采用X.509證書作為服務憑證,并且這個證書的主題名稱是一個DNS,用戶端可以采用DnsEndpointIdentity來對服務證書進行認證。在基于SPN的Windows認證下,并且SPN是基于一個DNS,用戶端也可以采用DnsEndpointIdentity認證服務。換句話會說,對于如下如下表示的DnsEndpointIdentity和SpnEndpointIdentity,在Windows認證下具有相同的認證效果。

服務端和用戶端的終結點都可以設定這個表示服務身份辨別的EndpointIdentity,不過對于整個服務認證機制,EndpointIdentity之于服務端和用戶端終結點具有不同的作用。服務端終結點設定的EndpointIdentity用于中繼資料釋出,用戶端終結點設定EndpointIdentity最終用于對服務的認證。

一般情況下,在進行服務寄宿的時候,終結點的EndpointIdentity無需指定,因為WCF會根據綁定采用的用戶端憑證類型和寄宿程序運作的Windows帳号為你生成相應的EndpointIdentity。終結點的EndpointIdentity最終會成員中繼資料的一部分被寫入服務的WSDL中。比如說,我們采用IIS的方式寄宿服務,終結點采用Transport模式的WS2007HttpBinding,EndpointIdentity對應在WSDL部分的内容将會如下面的XML片斷所示。由于IIS(IIS

6或之後版本)在Network

Servier帳号下執行,是以預設會使用SPN作為服務身份辨別(SPN中的Jinnan-Win7-X64為機器名稱)。

用戶端通過添加服務引用或者直接使用SvcUtil.exe導入中繼資料生成用戶端代碼和配置的時候,WSDL中的服務身份辨別會自動被寫入配置中。上述六種不同形式的EndpointIdentity在配置中的表示如下面的XML片斷所示。

如果你是通過單純程式設計的方式來建立用于進行服務調用的終結點,你可以按照如下的方式手工建立相應的EndpointIdentity對象。在建立作為終結點位址的EndpointAddress對象時,作為構造函數的參數傳入。一旦成功建立EndpointAddress對象,你就可以通過它的隻讀屬性Identity獲得你指定的EndpointIdentity。

被用于調用服務的用戶端終結點最終都關聯到一個EndpointIdentity對象上,而該EndpointIdentity對象代表了用戶端希望調服務的真實身份。用戶端在正式向服務發送功能性消息之前,會根據服務端提供的服務憑證和這個EndpointIdentity對服務實施認證。如果服務憑證與用戶端持有的服務身份相一緻,則認證成功,并開始後續的消息交換,否則雙方之間的互動到此為止。

在預設的情況下,正進行服務認證中用戶端和服務端有一個“協商(Negotiation)”的過程。用戶端通過此協商過程從服務端擷取服務憑證,是以我們将這個協商機制成為“服務憑證協商(Service

Credentials

Negotiation)”。對于Transport安全模式,服務憑證協商過程總是會發生,但是對于Message安全模式,你可以通過程式設計或者配置避免服務憑證協商。

如果服務憑證不能通過協商的方式即時地傳遞給用戶端,那麼必然要通過另外的方式遞交給它。對于Windows認證,需要用戶端和服務端必須出于同一域中。而對基于X.509證書的服務憑證,需要實作安裝到用戶端。抑制服務憑證協商會因避免證書的傳遞而對安全性有所增強,但是也會因為需要額外的證書遞交機制而帶來額外的負擔。如果你隻需要擁有相應證書的用戶端才能調用你的服務,不妨采用這種方式。

對于所有支援Message模式的綁定來說,隻有基于WS的綁定(WSHttpBinding、WS2007HttpBinding和WSDualHttpBinding)支援服務憑證協商。而開啟和關閉服務憑證協商可以通過設定MessageSecurityOverHttp類型的NegotiateServiceCredential屬性來實作。

不論是在進行服務寄宿還是服務調用的時候,你都可以通過程式設計的方式來關閉服務憑證協商機制。具體的程式設計方式,可以參考如下的代碼。

我們當然還是推薦采用配置的方式來控制服務憑證協商,在WSHttpBinding、WS2007HttpBinding和WSDualHttpBinding的<security>/<message>配置節點中,你可以找到negotiateServiceCredential配置屬性,這是開啟和關閉服務憑證協商的開關,相應的配置如下所示。

作者:蔣金楠

微信公衆賬号:大内老A

如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識别二維碼)關注個人公衆号(原來公衆帳号蔣金楠的自媒體将會停用)。

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

<a href="http://www.cnblogs.com/artech/archive/2011/06/12/Authentication_043.html" target="_blank">原文連結</a>

繼續閱讀