<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [WCF安全系列]服務憑證(Service Credential)與服務身份(Service Identity)

      采用TLS/SSL實現Transport安全的情況下,客戶端對服務證書實施認證。但是在默認情況下,這種認證僅僅是確保服務證書的合法性(通過數字簽名確保證書確實是由申明的CA頒發)和可信任性(證書或者CA證書存儲于相應的可信賴存儲區)。而WCF提供服務證書并不限于此,客戶端對服務認證的模式應該是這樣的:服務端預先知道了服務的身份,在進行服務調用之前,服務端需要提供相應的憑證用以輔助客戶端確認調用的服務具有預先確定的身份。對于這樣的服務認證模式,具有兩個重要的概念,即服務憑證和服務身份。

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

      一、服務憑證(Service Credential)

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

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

      而Windows認證具有兩種具體的實現,即KerberosNTLM。通過前面對Kerberos和NTLM的介紹,你應該知道只有Kerberos支持雙向認證,而NTLM則不能。因此,只有在基于域(Domain)的網絡環境中,基于Windows認證的服務認證才是可行的。而在工作組(Work Group)環境中,我們推薦使用基于證書的服務認證。

      服務認證方式的選擇決定于客戶端認證采用的方式,基本的策略是這樣的:如果采用Windows認證的方式對客戶端實施認證,服務認證同樣采用Windows認證。基于X.509證書的認證在非Windows客戶端認證下被采用。進一步地,如果客戶端憑證類型為Windows,那么WCF采用執行服務寄宿進程的Windows帳號對應的Windows憑證作為服務憑證。如果其他非Windows憑證作為客戶端憑證,你必須為服務顯式地指定一個X.509證書作為服務憑證。這也是為何在前面演示的實例中,當NetTcpBinding采用Transport安全模式,客戶端憑證被設置成None時,為何需要為服務指定一個X.509證書作為服務憑證的原因。

      在WCF的應用編程接口中,具有一個重要的服務行為ServiceCredentials。這個類并不簡單象它的名稱所表示的那樣用于進行服務憑證的設置,實際上需要在服務端執行的很多認證、授權行為都是通過ServiceCredentials(或者ServicePointManager的RemoteCertificateValidationCallback回調)來實現的。而在這里,我們暫時只關心如何通過ServiceCredentials為服務指定一個X.509證書作為服務憑證。關于這一點,已經在前面作過介紹了。

      如果服務采用基于X.509證書作為服務憑證,客戶端對服務的認證過程實際上分為兩個階段。第一個階段是驗證證書的合法性,在默認的情況下會采用ChainTrust認證模式,不過可以通過終結點行為ClientCredentials(或者ServicePointManager的RemoteCertificateValidationCallback回調)來設置不同的認證模式。關于具體對服務證書認證模式的設置在前面的實例演示(《TLS/SSL在WCF中的應用[SSL over TCP]》和《TLS/SSL在WCF中的應用[HTTPS]》)中已經有過介紹了。當通過以第一階段的認證之后,才會進入第二階段的認證,即通過比較服務證書和事先確立的服務身份信息進行對照進而確定服務是否是客戶端試圖訪問的服務,接下來討論關于服務身份的話題。

      二、服務身份(Service Identity)

      我們知道終結點時WCF最為核心的概念,終結點通過類型ServiceEndpoint表示。終結點具有ABC三要素分別表示地址、綁定和契約,其中地址通過EndpointAddress表示。如果你對EndpointAddress有一定的了解,你應該清楚該類具有一個只讀的Identity的屬性,對應的類型為EndpointIdentity,相關定義如下面的代碼片斷所示。

         1: public class ServiceEndpoint
         2: {
         3:     //其他成員
         4:     public EndpointAddress Address {  get; set; }
         5: }
         6: public class EndpointAddress
         7: {
         8:     //其他成員
         9:     public EndpointIdentity Identity { get; }
        10: }

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

         1: public abstract class EndpointIdentity
         2: {
         3:     //其他成員
         4:     public static EndpointIdentity CreateSpnIdentity(string spnName);
         5:     public static EndpointIdentity CreateUpnIdentity(string upnName);
         6:     public static EndpointIdentity CreateRsaIdentity(X509Certificate2 certificate);
         7:     public static EndpointIdentity CreateRsaIdentity(string publicKey);
         8:     public static EndpointIdentity CreateX509CertificateIdentity(X509Certificate2 certificate);
         9:     public static EndpointIdentity CreateDnsIdentity(string dnsName);
        10:    
        11:     public Claim IdentityClaim { get; }
        12: }
        13: public class SpnEndpointIdentity : EndpointIdentity
        14: {
        15:     //省略成員
        16: }
        17: public class UpnEndpointIdentity : EndpointIdentity
        18: {
        19:     //省略成員
        20: }
        21: public class DnsEndpointIdentity : EndpointIdentity
        22: {
        23:     //省略成員
        24: }
        25: public class RsaEndpointIdentity : EndpointIdentity
        26: {
        27:     //省略成員
        28: }
        29: public class X509CertificateEndpointIdentity : EndpointIdentity
        30: {
        31:     //省略成員
        32: }

      服務身份聲明通過屬性IdentityClaim表示,這些信息是為最終的認證服務服務的。從上面的代碼我們可能看出,EndpointIdentity實際上是一個抽象類,它具有如下幾個常用的子類:SpnEndpointIdentityUpnEndpointIdentityX509CertificateEndpointIdentityRsaEndpointIdentityDnsEndpointIdentity,分別表示不同的服務身份類型。這些個具體的EndpointIdentity可以通過對應的靜態方法CreateXxxIdentity創建。

      我們先來介紹一下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進行比較,從未確定服務運行在預先設定的機器或者某個域用戶帳號下。

         1: SPN:Host/<<HostName>> (Host/artech-win7-x64)
         2:  
         3: UPN:<<DomainName>>/<<UserName>>(Microsoft/BillGates)或者
         4: <<UserName>>@<<DomainName>> (BillGates@Microsoft)

      如果采用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認證下具有相同的認證效果。

         1: DnsEndpointIdentity:artech.com
         2: SpnEndpointIdentity: host/artech.com

      服務端和客戶端的終結點都可以設置這個表示服務身份標識的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為機器名稱)。

         1: <wsdl:definitions name="CalculatorService" targetNamespace="http://tempuri.org/">
         2:   ...
         3:   <wsdl:service name="CalculatorService">
         4:     <wsdl:port name="WS2007HttpBinding_ICalculator" binding="tns:WS2007HttpBinding_ICalculator">
         5:       <soap12:address location="https://jinnan-win7-x86/WcfServices/CalculatorService.svc"/>
         6:       <wsa10:EndpointReference>
         7:         <wsa10:Address>
         8:           https://jinnan-win7-x64/WcfServices/CalculatorService.svc
         9:         </wsa10:Address>
        10:         <Identity>
        11:           <Spn>host/Jinnan-Win7-X64</Spn>
        12:         </Identity>
        13:       </wsa10:EndpointReference>
        14:     </wsdl:port>
        15:   </wsdl:service>
        16: </wsdl:definitions>

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

         1: <system.serviceModel>
         2:   <client>
         3:     <endpoint address="http://jinnan-win7-x86/calculatorservice1" binding="ws2007HttpBinding" contract="Artech.WcfServices.Contracts.ICalculator">
         4:       <identity>
         5:         <userPrincipalName value="jinnan@contoso.com"/>
         6:         <servicePrincipalName value="host/jinnan-win7-x86"/>
         7:         <certificate encodedValue="f332bf17db3abb8f9a9a2694ba2c75da701bef0f"/>
         8:         <certificateReference storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" findValue="jinnan-win7-x86"/>
         9:         <rsa value="sdhjgr...djakjhg"/>
        10:         <dns value="jinnan-win7-x86"/>
        11:       </identity>
        12:     </endpoint>
        13:   </client>
        14: </system.serviceModel>

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

         1: EndpointIdentity identity = EndpointIdentity.CreateSpnIdentity(@"host\Jinnan-Win7-X86");
         2: EndpointAddress address = new EndpointAddress(new Uri("http://jinnan-win7-x64/calculatorservice"),identity);
         3: ServiceEndpoint endpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(ICalculator)),new WS2007HttpBinding(),address);
         4: using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(endpoint))
         5: {
         6:     ICalculator calculator = channelFactory.CreateChannel();
         7:     double result = calculator.Add(1, 2);
         8:     ...
         9: }

      三、服務憑證協商

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

      在默認的情況下,正進行服務認證中客戶端和服務端有一個“協商(Negotiation)”的過程。客戶端通過此協商過程從服務端獲取服務憑證,所以我們將這個協商機制成為“服務憑證協商(Service Credentials Negotiation)”。對于Transport安全模式,服務憑證協商過程總是會發生,但是對于Message安全模式,你可以通過編程或者配置避免服務憑證協商。

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

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

         1: public class MessageSecurityOverHttp
         2: {
         3:     //其他成員
         4:    public bool NegotiateServiceCredential {get;  set; }
         5: }

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

         1: //服務寄宿代碼
         2: using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
         3: {
         4:     WS2007HttpBinding binding = new WS2007HttpBinding( SecurityMode.Message);
         5:     binding.Security.Message.NegotiateServiceCredential = false;
         6:     host.AddServiceEndpoint(typeof(ICalculator), binding, "http://127.0.0.1:3721/calculatorservice");
         7:     host.Open();
         8:     ...
         9: }
        10: //客戶端代碼
        11: EndpointAddress address = new EndpointAddress("http://jinnan-win7-x64/calculatorservice");
        12: WS2007HttpBinding binding = new WS2007HttpBinding(SecurityMode.Message);
        13: binding.Security.Message.NegotiateServiceCredential = false;
        14: ServiceEndpoint endpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(ICalculator)), binding, address);
        15: using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(endpoint))
        16: {
        17:     ICalculator calculator = channelFactory.CreateChannel();
        18:     double result = calculator.Add(1, 2);
        19:     ...
        20: }

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

         1: <system.serviceModel>
         2:   <bindings>
         3:     <ws2007HttpBinding>
         4:       <binding name="transportWS2007HttpBinding">
         5:         <security mode="Message">
         6:           <message clientCredentialType="UserName" negotiateServiceCredential="false"/>
         7:         </security>
         8:       </binding>
         9:     </ws2007HttpBinding>      
        10:   </bindings>
        11: ...
        12: </system.serviceModel>
      posted @ 2011-06-12 11:40  Artech  閱讀(10825)  評論(7)    收藏  舉報
      主站蜘蛛池模板: 国产一区在线播放av| 国产99视频精品免费视频36| 成人3d动漫一区二区三区 | 色综合久久蜜芽国产精品| 高清在线一区二区三区视频| 福利一区二区在线视频| 日韩欧美人妻一区二区三区| 57pao成人国产永久免费视频| 桃花岛亚洲成在人线AV| 东安县| 视频一区视频二区中文字幕| 国产精品午夜福利视频| 钟祥市| 久久久精品94久久精品| 国产国产乱老熟女视频网站97| 久爱无码精品免费视频在线观看| 日韩本精品一区二区三区| 天堂网亚洲综合在线| 里番全彩爆乳女教师| 国产对白老熟女正在播放| 铁力市| 久久久久久久一线毛片| 亚洲第一精品一二三区| 牙克石市| 97久久久精品综合88久久| 日本中文字幕乱码免费| 国产中年熟女高潮大集合| 亚洲AV日韩AV永久无码下载| 成人3D动漫一区二区三区| 精品国产综合一区二区三区| 国产成人精品a视频一区| 麻豆成人久久精品二区三| 亚洲精品喷潮一区二区三区| 日本极品少妇videossexhd| 在线观看潮喷失禁大喷水无码| 好屌草这里只有精品| 精品国产免费人成在线观看| 日日爽日日操| 亚洲国产成人AⅤ片在线观看| 亚洲高清aⅴ日本欧美视频 | 国产美女精品一区二区三区|