文章出處

綁定可指定在與終結點通話時所使用的通信機制,并指示如何連接到終結點。綁定由一些元素組成,這些元素指定如何對 Windows Communication Foundation (WCF) 通道進行分層以提供所需的通信功能,包括采用什么基礎傳輸協議,TCP或Http等,使用什么協議保證消息的安全性,比如HTTPS或者WS-security,傳輸的消息的編碼方式,比如TEXT還是MTOM。

WCF中有多種binding形式,多種安全模式,多種身份驗證方式,這些組合在一起可以形成太多的組合。

本文將把各種典型的安全模式、各種綁定和客戶端驗證方式組合分別用實例進行配置并測試驗證。這一篇是專門討論BasicHttpBinding綁定的。

 

測試環境

l  服務端:

服務器名:win2008

操作系統:Windows server 2008

開發環境:visual studio 2008

運行環境:.net framework 3.5

Web服務器: IIS 7.0

瀏覽器:IE 7.0

l  客戶端:

服務端機器同時充當測試客戶端機器,同時準備了一臺win2003的機器做測試客戶端:

計算機名:win2003base2

操作系統:Windows server 2003

運行環境:.net framework 3.5

瀏覽器:IE 7.0

 

共用測試WCF服務類

所有測試都是用同樣的服務端contract和實現這個contract的service:

[ServiceContract(Namespace = "http://chnking.com")]

public interface IGetIdentity

{

    [OperationContract]

    string Get(string ClientIdentity);

}

public class GetIdentity : IGetIdentity

{

    public string Get(string ClientIdentity)

    {

        return ("服務端Identity 是'" + ServiceSecurityContext.Current. PrimaryIdentity.Name +

            "'\n\r客戶端Identity是 '" + ClientIdentity + "'");

    }

}

代碼很簡單,一個contract提供了一個Get方法,接收一個string參數,返回一個string參數。在后面的測試中,客戶端把客戶端安全上下文的Identity發送到服務端,服務端返回服務端安全上下文的Identity給客戶端。

 

一、  basicHttpBinding

這種綁定適用于與符合 WS-Basic Profile 的 Web 服務(例如基于 ASP.NET Web 服務 (ASMX) 的服務)進行的通信。此綁定使用 HTTP 作為傳輸協議,并使用文本/XML 作為默認的消息編碼。

basicHttpBinding的默認安全模式是None,即沒有任何安全設置,消息都以明文傳送,對客戶端也不進行驗證。

但是basicHttpBinding綁定可以實現安全傳輸,也可以通過傳輸層和消息層來保證消息的安全性。

basicHttpBinding設置為Transport安全模式,傳輸層的安全是使用IIS的安全機制,比如基本身份驗證、集成windows驗證、SSL安全通道等等。

basicHttpBinding設置為Message安全模式,消息層使用WS-Security保證消息的安全性,Message模式只支持客戶端Certificate驗證。

 

1、 安全模式None

這部分的測試代碼:basicHttpBinding_None.rar

basicHttpBinding綁定默認不提供安全性,默認的安全模式是None,不提供任何安全性,WCF提供這種方式只是為了跟WS-Basic Profile 的 Web 服務兼容。WCF的其它綁定默認都是提供安全性的。

這種方式的安全性:

完整性

不提供

保密性

不提供

服務端身份身份驗證

不提供

客戶端身份驗證

無,并忽略客戶端驗證的其他方式設置,固定為None

本例采用全代碼方式,不使用配置文件。

服務端代碼:

internal class MyServiceHost

{

    internal static ServiceHost myServiceHost = null;

    internal static void Main()

    {

        //設置BasicHttpBinding綁定

        BasicHttpBinding myBinding = new BasicHttpBinding();

        //安全模式None

        myBinding.Security.Mode = BasicHttpSecurityMode.None;

        Uri baseAddress = new Uri("http://localhost:8056/WCFService/");

        myServiceHost = new ServiceHost(typeof(GetIdentity), baseAddress);

        ServiceEndpoint myServiceEndpoint = myServiceHost.AddServiceEndpoint(typeof(IGetIdentity), myBinding, "GetIdentity");

        ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();

        behavior.HttpGetEnabled = true;

        behavior.HttpGetUrl = new Uri("http://localhost:8057/mex");

        myServiceHost.Description.Behaviors.Add(behavior);

        myServiceHost.Open();

        Console.WriteLine("Service started!");

        Console.ReadLine();

        myServiceHost.Close();

    }

}

客戶端代碼:

static void Main(string[] args)

{

    BasicHttpBinding myBinding = new BasicHttpBinding();

    myBinding.Security.Mode = BasicHttpSecurityMode.None;

    EndpointAddress ea = new EndpointAddress("http://localhost:8056/WCFService/GetIdentity");

    GetIdentityClient gc = new GetIdentityClient(myBinding, ea);

    //執行代理類Get方法

    string result = gc.Get(WindowsIdentity.GetCurrent().Name);

    Console.WriteLine(result);

    Console.ReadLine();

}

運行后,使用TCPTrace工具抓客戶端和服務端的通訊數據。

客戶端發請求:

POST /WCFService/GetIdentity HTTP/1.1

Content-Type: text/xml; charset=utf-8

SOAPAction: "http://chnking.com/IGetIdentity/Get"

Host: localhost:8055

Content-Length: 186

Expect: 100-continue

Connection: Keep-Alive

 

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

     <s:Body>

         <Get xmlns="http://chnking.com">

              <ClientIdentity>WIN2008\Administrator</ClientIdentity>

         </Get>

     </s:Body>

</s:Envelope>

服務端返回的數據:

HTTP/1.1 100 Continue

 

HTTP/1.1 200 OK

Content-Length: 245

Content-Type: text/xml; charset=utf-8

Server: Microsoft-HTTPAPI/2.0

Date: Thu, 02 Oct 2008 14:42:16 GMT

 

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

     <s:Body>

         <GetResponse xmlns="http://chnking.com">

              <GetResult>

                   Identity of server is''

                   &#xD;Identity of client is 'WIN2008\Administrator'

              </GetResult>

         </GetResponse>

     </s:Body>

</s:Envelope>

可以看出,這種方式的請求和響應跟web services是一致的,兼容的。

可以用這種綁定方式發布WCF服務,使用傳統的web services客戶端消費服務,也可以用這種綁定方式作為客戶端,消費web services發布的服務。

 

2、 安全模式Message - 客戶端驗證:Certificate

這部分的測試代碼: basicHttpBinding_Message_Certificate.rar

basicHttpBinding綁定的Message安全模式,客戶端Certificate驗證。此時將使用服務端證書,通過WS-Security協議保證消息安全。

WS-Security 規范已經定義了通過使用安全性令牌來安全地交換消息的基本機制。WS-Trust 規范以這個模型為基礎進行構建,定義了如何發出和交換這些安全性令牌。

WS-Trust原理上類似SSL或TLS的機制,客戶端不必有服務端的證書,服務端證書可以通過消息交換交換到客戶端。WS-Security 規范則不同,它沒有定義安全令牌的交換,所以客戶端需要事先把安裝服務端證書,并在通訊時指定服務端證書。

 

這種方式的安全性:

完整性

使用服務端證書,通過WS-Security規范建立的安全通道

保密性

使用服務端證書,通過WS-Security規范建立的安全通道

服務端身份身份驗證

服務端證書提供

客戶端身份驗證

客戶端證書提供

 

2.1.   獲得和安裝證書

同時客戶端驗證設置為Certificate,就需要提供客戶端證書以驗證客戶端身份。

所有這里需要在服務端和客戶端分別安裝證書。

 

這里用Makecert.exe工具生成證書,使用下面的命令:

makecert -sr localmachine -ss My -n CN=win2008 -sky exchange -pe -r

這是服務端證書,win2008是服務端的機器名。

 

makecert -sr currentuser -ss My -n CN=TestClient -sky exchange -pe -r

這是客戶端證書。

 

 

2.2.   服務端代碼:

internal static ServiceHost myServiceHost = null;

 

internal static void Main()

{

    BasicHttpBinding myBinding = new BasicHttpBinding();

    myBinding.Security.Mode = BasicHttpSecurityMode.Message;

    myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;

    Uri baseAddress = new Uri("http://win2008:8056/WCFService/");

    myServiceHost = new ServiceHost(typeof(GetIdentity), baseAddress);

    ServiceEndpoint myServiceEndpoint = myServiceHost.AddServiceEndpoint

        (typeof(IGetIdentity), myBinding, "GetIdentity");

    //設置服務端證書

    myServiceHost.Credentials.ServiceCertificate.SetCertificate("CN=win2008");

    //設置不驗證客戶端證書的有效性

    myServiceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode =

        System.ServiceModel.Security.X509CertificateValidationMode.None;

    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();

    behavior.HttpGetEnabled = true;

    behavior.HttpGetUrl = new Uri("http://win2008:8057/mex");

    myServiceHost.Description.Behaviors.Add(behavior);

    myServiceHost.Open();

    Console.WriteLine("Service started!");

    Console.ReadLine();

    myServiceHost.Close();

}

 

2.3.   客戶端代碼:

static void Main(string[] args)

{

    BasicHttpBinding myBinding = new BasicHttpBinding();

    myBinding.Security.Mode = BasicHttpSecurityMode.Message;

    myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;

    EndpointAddress ea = new EndpointAddress("http://win2008:8056/WCFService/GetIdentity");

    GetIdentityClient gc = new GetIdentityClient(myBinding, ea);

    //設置客戶端證書

    gc.ClientCredentials.ClientCertificate.SetCertificate("CN=TestClient",

        StoreLocation.CurrentUser, StoreName.My);

    //指定服務端證書

    gc.ClientCredentials.ServiceCertificate.SetDefaultCertificate("CN=win2008",

                StoreLocation.LocalMachine, StoreName.My);

    //不驗證服務端證書的有效性

    gc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =

        System.ServiceModel.Security.X509CertificateValidationMode.None;

    //執行代理類Get方法

    string result = gc.Get(WindowsIdentity.GetCurrent().Name);

    Console.WriteLine(result);

    Console.ReadLine();

    gc.Close();

}

這里客戶端的代碼需要特別注意的是,除了指定客戶端自己的證書外,還必須指定服務端證書。

 

2.4.   測試

 

 

 

3、 Transport – 客戶端驗證:None

這部分的測試代碼:basicHttpBinding_Transport.rar

BasicHttpBinding綁定默認不提供安全性,如果設置了Transport安全模式,需要通過IIS承載WCF服務,利用HTTPS協議來提供Transport層面的安全性。

這種方式的安全性:

完整性

服務端證書通過SSL保證

保密性

服務端證書通過SSL保證

服務端身份身份驗證

服務端證書通過SSL驗證服務端

客戶端身份驗證

 

 

3.1.   新建WCF服務應用程序

在VS2008中新建一個承載WCF的“WCF服務應用程序”:

    

WCF服務應用程序默認使用visual studio開發服務器承載web應用,這里需要使用HTTPS來保證傳輸安全,要配置服務端證書和SSL通道,所以改成用IIS承載服務。打開這個新建的項目屬性,在web標簽中,修改成這樣:

        

 

項目建立后,自動生成.svc文件和.svc.cs文件,這就是承載WCF服務的文件。

將.svc文件內容改成這樣:

<%@ ServiceHost Language="C#" Debug="true" Service="WcfIISHostService.GetIdentity "%>

WcfIISHostService.CalculatorService是要承載的WCF服務類,指向.svc.cs文件中的服務類。

把.svc.cs文件放到App_Code代碼目錄下,并把內容改成前面的統一的服務端contract和實現這個contract的service的代碼。

 

3.2.   配置服務端web.config

WCF的相關設置都在web.config文件中體現:

<system.serviceModel>

     <bindings>

         <basicHttpBinding>

              <binding name="NewBinding0">

                   <security mode="Transport">

                       <transport clientCredentialType="None" />

                   </security>

              </binding>

         </basicHttpBinding>

     </bindings>

     <services>

         <service behaviorConfiguration="WcfIISHostService.Service1Behavior" name="WcfIISHostService.GetIdentity">

              <endpoint address="GetIdentity" binding="basicHttpBinding" bindingConfiguration="NewBinding0" contract="WcfIISHostService.IGetIdentity">

                   <identity>

                       <dns value="localhost" />

                   </identity>

              </endpoint>

         </service>

     </services>

     <behaviors>

         <serviceBehaviors>

              <behavior name="WcfIISHostService.Service1Behavior">

                   <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />

                   <serviceDebug includeExceptionDetailInFaults="true" />

              </behavior>

         </serviceBehaviors>

     </behaviors>

</system.serviceModel>

指定的綁定是basicHttpBinding,綁定的安全模式選擇的是Transport,客戶端驗證方式為None。這樣的設置實際上就是指定服務端使用SSL安全通道跟客戶端通訊,來保證消息的完整性和私密性,但是不要求驗證客戶端身份。

IIS承載的WCF,BaseAddress就是svc文件的URL,所以配置文件中不需要制指定service的BaseAddress。

 

3.3.   設置服務端IIS設置( SSL服務端證書)

3.3.1.   設置IIS允許匿名訪問

要驗證客戶端身份,所以IIS7.0中需要設置WCF服務應用程序為可匿名訪問。

3.3.2.   獲得證書

需要在IIS 7.0上承載WCF服務的那個網站設置服務端證書并配置SSL。

這里用Makecert.exe工具生成一個測試用的證書,使用下面的命令:

makecert -sr localmachine -ss My -n CN=win2008 -sky exchange -pe -r

其中cn=win2008,表示證書的名稱為win2008,跟服務器名一致。

關于如何獲得證書,如何管理證書,詳細信息請參考《使用X.509數字證書加密解密實務(一)-- 證書的獲得和管理

上面的命令行執行后,生成名稱為win2008的證書,并存放到服務器的當前計算機的個人證書存儲區:

     

3.3.3.   IIS7.0中配置SSL

IIS7.0跟IIS6.0比,改變相當的大,無論從底層還是從操作界面,改變都是巨大的。本例承載WCF服務的實在default web site下的一個應用程序WcfIISHostService,所以要給default web site增加一個https的binding,在IIS7.0中點擊default web site選Edit Binding:

          

 

打開site Bindings窗口,按Add…增加一個Binding,這里增加https的binding,端口默認的443,最重要的是要選擇一個SSL的證書,這里因為前面已經在服務器上生成并安裝了win2008的證書,選擇這個證書:

         

之后再default web site下選擇WcfIISHostService應用程序,在IIS界面中間的Features View中雙擊SSL Settings,配置這個應用程序的SSL設置:

     

 

3.3.4.   SSL服務端證書需要特別注意之處

l  SSL服務端證書被保存到當前計算機的個人證書

只有在當前計算機證書位置下的證書才能作為SSL服務端的證書。

l  證書名跟服務器名或域名一定要一致

作為WEB服務器的SSL證書的證書名需要跟web服務器名稱(內網用機器名訪問時)或者域名(外網以域名訪問時)一致,否則:

用IE客戶端瀏覽時提示“此網站出具的安全證書是為其他網站地址頒發的。”

在WCF的客戶端則會導致錯誤:無法為 SSL/TLS 安全通道與頒發機構“服務器名”建立信任關系。

 

l  客戶端需要把SSL服務端證書及證書鏈中所有證書都放到當前用戶的受信任證書頒發機構中,否則:

用IE客戶端瀏覽時提示“此網站出具的安全證書不是由受信任的證書頒發機構頒發的。”如圖:

 

在WCF的客戶端導致同樣的錯誤:無法為 SSL/TLS 安全通道與頒發機構“服務器名”建立信任關系。

當證書不受信任時,可以在IE瀏覽器中瀏覽證書,并把服務端證書安裝到本機計算機,并放到當前用戶的受信任證書頒發機構存儲區中,如果有證書鏈,則需要把所有的證書都放到當前用戶的受信任證書頒發機構存儲區中。

3.4.   建立客戶端

新建一個Console應用WCFClient,引用前面在IIS7.0中建的WCF服務應用,引用時也需要用HTTPS引用,本例的引用地址為:https://win2008/WcfIISHostService/Service1.svc,引用過程中同樣是通過SSL通道,需要驗證服務端證書。

引用WCF服務后,在項目中生成包含客戶端代理的cs代碼文件,和app.config配置文件,本例中不使用配置,都是用代碼進行配置,所以把app.config排除。

客戶端代碼:

static void Main(string[] args)

{

    //使用BasicHttpBinding綁定

    BasicHttpBinding myBinding = new BasicHttpBinding();

    //使用Transport安全模式

    myBinding.Security.Mode = BasicHttpSecurityMode.Transport;

    //客戶端驗證為None,不驗證客戶端

    myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

    //客戶端Endpoint地址,指向服務端Endpoint的地址

    EndpointAddress ea = new EndpointAddress("https://win2008/WcfIISHostService/Service1.svc/GetIdentity");

    GetIdentityClient gc = new GetIdentityClient(myBinding, ea);

    //執行代理類Get方法

    string result = gc.Get(WindowsIdentity.GetCurrent().Name);

    Console.WriteLine(result);

    Console.ReadLine();

}

3.5.   測試

測試中希望能對WCF服務端進行調試,能斷點,看斷點處的一些上下文變量,比如需要查看服務端收到請求后的客戶端身份。

在VS2008中將WcfIISHostService項目設為啟動項目,運行,提示以下問題:

 

經檢查WcfIISHostService項目的屬性設置需要做些修改,原來項目的URL為:http://localhost/WcfIISHostService,需要改成如下圖這樣:

 

因為WcfIISHostService應用程序在IIS7.0中設置了需要SSL,所以需要改成https,又因為給web網站的證書的名稱是win2008,所原來里的localhost改成機器名win2008,跟證書名匹配,這樣調式運行時就不會提示證書不匹配的了。

 

在實際測試中發現VS2008非常有意思的功能,如果把客戶端console的項目設為啟動項目,同時在WCF服務項目中設置一個斷點,在VS2008按F5啟動調試,當客戶端發送請求到服務端,服務端代碼運行到設置的斷點時,它會在斷點處停下來,實際效果就像運行WCF服務的進程自動被附加到VS2008調式環境中。這給調試帶來了很大的便利。

         

上圖就是在客戶端發送請求到服務端,在服務端執行Add方法時遇到斷點中斷的截圖,斷點時,查看ServiceSecurityContext.Current,這個ServiceSecurityContext類表示WCF運行時的安全上下文,表示客戶端的身份,這里IsAnonymous=true,表示是匿名用戶。因為沒有要求客戶端身份驗證,應該是匿名的。

客戶端的返回結果,可以看出從服務端獲得的Identity是空,表示匿名:

 

 

4、 Transport – 客戶端驗證:Basic

這部分的測試代碼:basicHttpBinding_Transport.rar

這部分測試HttpBinding設置為Transport安全模式,同時客戶端驗證設置為Basic驗證時的情況。

實際上HttpBinding的Transport安全模式,WCF服務端是由IIS承載的,所以它的身份驗證使用IIS的身份驗證模式。

Basic身份驗證,是由客戶端提供服務端的windows用戶的用戶名和密碼,用戶名以明碼方式發送,密碼以base64編碼方式發送,base64編碼可以看作是明碼。服務端收到客戶端發送的用戶名和密碼后,跟服務端的windows用戶中的用戶去比對,如有匹配的則驗證客戶端的身份。

關于IIS的各種身份驗證的進一步信息,可以參考《IIS的各種身份驗證詳細測試》。

這種方式的安全性:

完整性

服務端證書通過SSL保證

保密性

服務端證書通過SSL保證

服務端身份身份驗證

服務端證書通過SSL驗證服務端

客戶端身份驗證

客戶端提供服務端windows用戶的用戶名和密碼,服務端驗證。客戶端傳送到服務端的用戶名和密碼同樣被SSL加密。

 

測試項目在前面“Transport – 客戶端驗證:None”測試項目中稍作修改即可:

4.1.   服務端修改

修改web.config配置文件:

<security mode="Transport">

     <transport clientCredentialType="None" />

</security>

這部分改成 -à

<security mode="Transport">

     <transport clientCredentialType="Basic" />

</security>

 

4.2.   客戶端修改

客戶端代碼中:

//客戶端驗證為None,不驗證客戶端

myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

這部分改成 -à

//客戶端驗證為Basic

myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

之后在新建客戶端代理對象gc后,增加如下代碼:

//客戶端為Basic時,客戶端提供用戶名和密碼

gc.ClientCredentials.UserName.UserName = "chnking";

gc.ClientCredentials.UserName.Password = "jjz666";

這里的chnking是在服務端系統中的一個用戶。

4.3.   測試

先在win2008的機器上同時運行服務端和客戶端,系統以Administrator登錄。

運行結果:

 

服務端Identity為win2008\chnking,客戶端發送到服務端的用戶名是chnking,IIS驗證用戶名和密碼是不是能跟服務端windows中用戶匹配,結果匹配到了chnking用戶,因此服務端WCF服務代碼獲得了chnking的Identity,符合預期。

 

下面再把客戶端放到第二臺機器win2003base2上進行測試,同樣系統也以Administrator登錄。

運行結果:

 

服務端Identity為win2008\chnking,客戶端發送到服務端的用戶憑據是chnking,IIS驗證用戶名和密碼是不是能跟服務端windows中用戶匹配,同樣匹配到了chnking用戶,因此服務端WCF服務代碼獲得了chnking的Identity,符合預期。

 

5、 Transport – 客戶端驗證:Ntlm

這部分的測試代碼:basicHttpBinding_Transport.rar

這部分測試HttpBinding設置為Transport安全模式,同時客戶端驗證設置為Ntlm驗證時的情況。

Ntlm身份驗證,是由客戶端提供當前登錄windows用戶的用戶憑據(用戶名和密碼)發送到服務端進行驗證的方式,當然這里密碼的傳送有個質詢和加密的過程,過程中不傳送密碼本身。這個驗證過程不走SSL通道也是安全的。

服務端收到客戶端發送的用戶名和密碼后,如果客戶端發送來的是域用戶則服務端驗證客戶端域用戶的身份,如果客戶端發送來的是一般windows用戶,則服務端驗證服務器本身的用戶。

這種方式,如果是一般windows用戶驗證,一定要保證客戶端的用戶和密碼跟服務端的用戶和密碼都要一致。

這種方式的安全性:

完整性

服務端證書通過SSL保證

保密性

服務端證書通過SSL保證

服務端身份身份驗證

服務端證書通過SSL驗證服務端

客戶端身份驗證

客戶端提供當前登錄windows用戶的用戶憑據(用戶名和密碼),服務端驗證。客戶端傳送到服務端的用戶名和密碼同樣被SSL加密。

 

測試項目在前面“Transport – 客戶端驗證:None”測試項目中稍作修改即可:

5.1.   服務端修改

修改web.config配置文件:

<security mode="Transport">

     <transport clientCredentialType="None" />

</security>

這部分改成 -à

<security mode="Transport">

     <transport clientCredentialType="Ntlm" />

</security>

 

5.2.   客戶端修改

客戶端代碼中:

//客戶端驗證為None,不驗證客戶端

myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

這部分改成 -à

//客戶端驗證為Basic

myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;

 

5.3.   測試

先在win2008的機器上同時運行服務端和客戶端,系統以Administrator登錄。

運行結果:

 

服務端Identity為win2008\Administrator,客戶端發送到服務端當前登錄的用戶Administrator,IIS驗證用戶名和密碼是不是能跟服務端windows中用戶匹配,結果匹配到了Administrator用戶,因此服務端WCF服務代碼獲得了Administrator的Identity,符合預期。

 

下面再把客戶端放到第二臺機器win2003base2上進行測試,win2003base2不在域,系統以機器win2003base2的chnking用戶登錄。

運行結果:

 

服務端Identity為win2008\chnking,客戶端發送到服務端的用戶憑據是一般windows用戶chnking,IIS驗證用戶名和密碼是不是能跟服務端windows中用戶匹配,匹配到了chnking用戶,因此服務端WCF服務代碼獲得了chnking的Identity,符合預期。

5.4.   訪問權限控制

客戶端身份驗證采用了Ntlm或者Windows模式時,客戶端身份實際上就映射到了服務端自身的Windwos用戶或者域用戶,也就可以對客戶端的訪問權限就行控制了。

在服務端的實現contract的服務中對相應的方法做訪問限制,做法是在方法的前面加上PrincipalPermission屬性,比如:

[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]

public string Get(string ClientIdentity)

{

    return ("服務端Identity 是 '" + ServiceSecurityContext.Current.WindowsIdentity.Name +

        "'\n\r客戶端Identity 是 '" + ClientIdentity + "'");

}

表示Get方法只有服務端Administrators用戶組的成員可以訪問。

測試一下上面的訪問權限控制是否正確。

在win2003base2機器上用administrator登錄,運行客戶端,結果如下:

 

客戶端的administrator映射到服務端的administrator用戶,是服務端Administrators用戶組的成員,有權限運行Get方法,反正正常的結果。

再測試在win2003base2機器上用chnking用戶登錄,運行客戶端,結果如下:

 

客戶端chnking用戶跟服務端的chnking同名同密碼,在服務端的Identity就是chnking,chnking不是服務端的Administrators用戶組的成員,所以沒有權限訪問Get方法,所以服務端拋出“Access is denied”異常。

 

6、 Transport – 客戶端驗證:Windows

這種驗證方式跟Ntlm方式基本相同,都是驗證客戶端的windows用戶憑據,是一般windows用戶驗證服務端本地windows用戶,是域用戶的驗證與用戶。有點不同的是,Windows驗證跟客戶端有個協商過程,如果客戶端機器和服務端機器都在域,并且客戶端也是以域用戶登錄,則客戶端會使用kerberos驗證方式,傳送客戶端用戶的kerberos憑據到服務端進行驗證,否則客戶端跟服務端之間使用使用Ntlm驗證。

跟Ntlm模式比較,在其他配置和代碼方面是一樣的。

7、 Transport – 客戶端驗證:Certificate

IIS 7.0配置客戶端證書在服務端映射到windows用戶實在是太麻煩,沒有跟IIS6.0類似的用戶界面就行配置,需要很多手工操作,真是倒退。算了,不去搞這個了。

有興趣的去看一下如何配置IIS 7.0的證書映射的文章:《IIS 7 Walkthrough: One to One Client Certificate Mapping Configuration》。

客戶端代理類帶上客戶端證書的操作類似這樣:

proxyClass.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My,X509FindType.FindBySubjectName, "win2008Client");

我沒興趣做這個測試了,實際使用中還是message安全模式使用的多些,優點也多些,就不找這個麻煩,用IIS來驗證客戶端證書了。


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()