程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> WCF安全系列(一) - basicHttpBinding

WCF安全系列(一) - basicHttpBinding

編輯:關於.NET

一、basicHttpBinding.2

1、安全模式None.3

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

2.1.獲得和安裝證書...5

2.2.服務端代碼:...5

2.3.客戶端代碼:...6

2.4.測試...7

3、Transport – 客戶端驗證:None.7

3.1.新建WCF服務應用程序...7

3.2.配置服務端web.config.8

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

3.3.1.設置IIS允許匿名訪問...9

3.3.2.獲得證書...9

3.3.3.IIS7.0中配置SSL.10

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

3.4.建立客戶端...14

3.5.測試...15

4、Transport – 客戶端驗證:Basic.16

4.1.服務端修改...17

4.2.客戶端修改...17

4.3.測試...17

5、Transport – 客戶端驗證:Ntlm...18

5.1.服務端修改...19

5.2.客戶端修改...19

5.3.測試...19

5.4.訪問權限控制...20

6、Transport – 客戶端驗證:Windows.21

7、Transport – 客戶端驗證:Certificate.21

綁定可指定在與終結點通話時所使用的通信機制,並指示如何連接到終結點 。綁定由一些元素組成,這些元素指定如何對 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.Certificate ValidationMode =
     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.CertificateVali dationMode =
     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來驗證客戶端證書了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved