WCF分佈式安全開發實踐(11):消息安全模式之Certificate身份驗證:Message_Certificate_WSHttpBinding

原文:WCF分佈式安全開發實踐(11):消息安全模式之Certificate身份驗證:Message_Certificate_WSHttpBinding 

今天繼續介紹WCF分佈式安全開發實踐(11):消息安全模式之Certificate身份驗證:Message_Certificate_WSHttpBinding 。本文介紹的內容主要是:主要是消息安全模式的證書身份驗證方式,基於WSHttpBinding綁定協議的實現過程。主要內容:基本概念,然後是製作證書、服務端配置、客戶端配置、總結。這裏應該和Transport傳輸安全模式之證書身份驗證對應,但是消息安全模式這裏不使用https。安全基於TLS,傳輸層安全連接。 

【0】消息安全模式之證書客戶端身份驗證:

       消息安全模式之證書身份驗證需要服務器需要一個有效的可用於TLS 加密和向客戶端驗證服務身份的 X.509 證書,並且客戶端必須信任此服務器證書。而客戶端同樣要提供一個有效的證書,來證明自己的身份。 這裏使用http協議。建議安全上下文以後,使用共享安全上下文對SOAP消息進行加密和簽名。使用證書對客戶端和服務進行身份驗證。也就是客戶端提供有效證書纔可以訪問此服務。

1.身份驗證(服務器):提供證書,(使用 HTTP)用於初始會話協商和證明服務身份。

2.身份驗證(客戶端):客戶端證書進行身份驗證

   WCF消息安全模式之證書身份驗證的架構如下:

WCF分佈式安全開發實踐(11):消息安全模式之Certificate身份驗證:Message_Certificate_WSHttpBinding - wxfclnice - 逍遙彩上飛的博客    

    客戶端建立TLS安全上下文以後,會使用商定的密碼對消息簽名,客戶端使用證書加密數據,服務端使用證書解密數據,保證數據的安全和機密性,消息簽名放置被篡改。

   這裏客戶端提供的是有效的證書,服務器端進行驗證。

   下面是製作證書的過程,和傳輸安全模式的過程一樣,這裏直接使用相同證書製作工具,新啓用端口8001。

【1】製作證書:

(1)使用makecert 工具:Microsoft Visual Studio 2008-->Visual Studio Tools-->Visual Studio 2008 命令提示行。

輸入:makecert -sr localmachine -ss My -n CN=WCFServerPK -sky exchange -pe -r

輸入:makecert -sr localmachine -ss My -n CN=WCFClientPK -sky exchange -pe -r。

-這裏製作了連個證書,主要只使用一個WCFServerPK,可以到出密鑰文件pfx,後續我們要導入到其他存儲區,設置爲信任的證書。WCFClientPK -是爲以後文章準備的,也是可以設置爲信任的證書。

 (2) 打開瀏覽器---->Internet 選項----->內容----->證書----->個人,默認是保存到當前用戶CurrentUser,你會看到剛纔製作的證書。這個可以查看部分證書,但是功能有限。我們還是使用控制檯證書管理工具。

 

 (3)使用MMC建立證書控制單元查看證書的信息:

  開始--運行--MMC--控制檯--添加刪除單元--證書--當前用戶和計算機各添加一個。能查看和管理CurrentUser和LocalMachine的證書。如圖:

WCF分佈式安全開發實踐(11):消息安全模式之Certificate身份驗證:Message_Certificate_WSHttpBinding - wxfclnice - 逍遙彩上飛的博客

(4)導入證書到信任的人和信任的CA機構裏。步驟如下:

    1.導出證書文件,帶密鑰的pfx文件。使用mmc,保存到桌面位置(方便查找)。這裏記住你製作證書的密碼。要使用。

    2.導入證書到信任的人。使用任務-導入嚮導--選擇證書文件,導入即可。

    3.導入證書到信任的機構,使用任務-導入嚮導--選擇證書文件,導入即可。這個證書就被信任了。

【3】服務端配置:

   服務器證書配置完成以後,我們來配置服務端相關的文件,這裏簡單。也可以使用代碼來完成。

    (1)服務類定義:

    重複使用以前定義的服務類代碼。 這裏服務類就一個方法就是更具用戶的name來打印調用時間,代碼如下:

 //1.服務契約

    [ServiceContract(Namespace = "http://www.cnblogs.com/frank_xl/")]

    public interface IWCFService

    {

        //操作契約

        [OperationContract]

        string SayHello(string name);

    }

    //2.服務類,繼承接口。實現服務契約定義的操作

    public class WCFService : IWCFService

    {

        //實現接口定義的方法

        public string SayHello(string name)

        {

            Console.WriteLine("Hello! {0},Calling at {1} WCF分佈式安全開發實踐(11):消息安全模式之Certificate身份驗證:Message_Certificate_WSHttpBinding - wxfclnice - 逍遙彩上飛的博客", name,DateTime.Now.ToLongTimeString());

            return "Hello! " + name;

        }

    }

    (2)消息安全模式配置:

       使用消息安全模式,採用客戶端證書身份驗證策略,Message安全模式下的證書驗證方式配置信息如下:

 

 

    <wsHttpBinding>

      <binding name="BindingConfigration">

        <security mode="Message">

          <transport clientCredentialType="None"/>

          <message clientCredentialType="Certificate" negotiateServiceCredential="true" establishSecurityContext="true"/>

        </security>

      </binding>

    </wsHttpBinding>

   這裏允許啓用安全協商和建立安全上下文。這個配置要應用到服務的終結點配置上。纔會生效。

    (3)證書使用:

    服務器端證書主要是在建立TLS連接會話的時候,證明服務端的身份合法性。

    在服務行爲節點屬性裏配置使用證書WCFServerPK,其它設置採用默認方式。這裏和WCF分佈式安全開發實踐(7):消息安全模式之匿名客戶端:Message_None_WSHttpBinding 配置一樣,具體代碼如下:

 

behaviors>

      <serviceBehaviors>

        <behavior name="WCFService.WCFServiceBehavior">

          <serviceMetadata httpGetEnabled="true" />

          <serviceDebug includeExceptionDetailInFaults="false" />

          <serviceCredentials>

              <serviceCertificate  storeName="My"  x509FindType="FindBySubjectName" findValue="WCFServerPK" storeLocation="LocalMachine"/>

          </serviceCredentials>

        </behavior>

      </serviceBehaviors>

    </behaviors>

    <bindings>

    這裏指定了服務端證書的查找位置和查找條件,我們證書存儲在LocalMachine 個人區域。使用標題進行查找。如果相同標題,需要制定唯一的查找條件。保證查找證書的唯一性。否則會出異常。

   (4)這裏我們不需要使用Https傳輸協議,直接使用http協議即可,服務終結點的配置信息如下:

    <services>

      <service behaviorConfiguration="WCFService.WCFServiceBehavior" name="WCFService.WCFService" >

        <endpoint 

          address="WCFService" 

          binding="wsHttpBinding" 

          bindingConfiguration="BindingConfigration"

          contract="WCFService.IWCFService">

        </endpoint>

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

        <host>

          <baseAddresses>

            <add baseAddress="http://localhost:8001/"/>

          </baseAddresses>

        </host>

      </service>

    </services>

   我們的服務元數據終結點使用基地址:http://localhost:8001/

【4】客戶端配置:

    這個過程和之前的傳輸安全模式下,參考WCF分佈式安全開發實踐(5):傳輸安全模式之Certificate身份驗證:Transport_Certificate_WSHttpBinding , 添加服務的過程一樣。直接引用。

    (1)引用元數據:

    因爲服務的元數據交換節點啓用了Http協議,我們在客戶端項目添加元數據地址http://localhost:8001/mex查找服務信息的時候,界面如下:

WCF分佈式安全開發實踐(11):消息安全模式之Certificate身份驗證:Message_Certificate_WSHttpBinding - wxfclnice - 逍遙彩上飛的博客    

   繼續就會添加完畢服務引用。過程和普通的添加服務元數據引用一樣,會產生客戶端相關代碼文件。輸入命名空間,現在我們點擊Ok。等待完成即可。  

    (2)配置文件:

    客戶端配置文件使用默認設置,主要是安全模式的設置要如下,與服務端匹配。使用證書驗證方式。

bindings>

            <wsHttpBinding>

                <binding name="WSHttpBinding_IWCFService">

                    <security mode="Message">

                        <transport clientCredentialType="None" proxyCredentialType="None"

                            realm="" />

                        <message clientCredentialType="Certificate" negotiateServiceCredential="true"

                            algorithmSuite="Default" establishSecurityContext="true" />

                    </security>

                </binding>

            </wsHttpBinding>

        </bindings>

    (3)客戶端證書:

        這裏我們要在配置文件裏提供客戶端的證書,也可以採用代碼方式提供客戶端證書。配置文件的方式比較簡單。

直接在endpointBehaviors裏設置以後,應用到終結點行爲配置上就可以了。代碼如下:

      <behaviors>

        <endpointBehaviors>

          <behavior name="endpointBehavior">

            <clientCredentials>

              <clientCertificate storeName="My"

                                 x509FindType="FindBySubjectName"

                                 findValue="WCFClientPK"

                                 storeLocation="CurrentUser"/>

            </clientCredentials>

          </behavior>

        </endpointBehaviors>

      </behaviors>

    (4)測試代碼:

      等待代碼生成結束,我們這裏就直接生成客戶端代理類的實例來調用服務進行測試。這裏客戶端在調用服務以前,必須信任證書,這裏我們使用了一段通用的代碼,來建立TLS使用。這裏會信任服務器的證書。代碼如下:

 public static class Util

    {

        /// <summary>

        /// Sets the cert policy.

        /// </summary>

        public static void SetCertificatePolicy()

        {

            ServicePointManager.ServerCertificateValidationCallback

                       += RemoteCertificateValidate;

        }

        /// <summary>

        /// Remotes the certificate validate.

        /// </summary>

        private static bool RemoteCertificateValidate(

           object sender, X509Certificate cert,

            X509Chain chain, SslPolicyErrors error)

        {

            // trust any certificate!!!

            System.Console.WriteLine("Warning, trust any certificate");

            return true;

        }

    }

   客戶端測試代碼很簡單,我們不需要提供客戶端證書了,因爲配置文件裏已經設置完畢。接下來就是通過客戶端代理來調用WCF服務。代碼如下:

       static void Main(string[] args)

        {

            try

            {

                Console.ForegroundColor = ConsoleColor.Green;

                WCFClient.ClientProxy.WCFServiceClient wcfServiceProxy = new WCFClient.ClientProxy.WCFServiceClient("WSHttpBinding_IWCFService");

                //通過代理調用SayHello服務

                string sName = "Frank Xu Lei  Message Certificate WSHttpBinding";

                string sResult = string.Empty;

                Util.SetCertificatePolicy();

                sResult = wcfServiceProxy.SayHello(sName);

                Console.WriteLine("Returned Result is {0}", sResult);

            }

            catch (Exception e)

            {

               Console.WriteLine("Exception : {0}", e.Message);

            }

            //For Debug

            Console.WriteLine("Press any key to exit");

            Console.Read();

            

        }

    這裏也可以使用代碼來設置證書wcfServiceProxy.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2("WCFClientPK.pfx", "password");WCFClientPK.pfx是導出的客戶端證書的文件,包含密鑰,密碼爲保護密碼。

  (4)測試結果:

   啓動宿主程序,然後啓動客戶端程序,客戶端成功調用服務,宿主打印的消息。如圖:

WCF分佈式安全開發實踐(11):消息安全模式之Certificate身份驗證:Message_Certificate_WSHttpBinding - wxfclnice - 逍遙彩上飛的博客

【5】總結

     Windows Communication Foundation (WCF) 服務和客戶端。WCF安全機制都是依賴現有的安全體系和框架來完成的。這裏的消息安全模式下的客戶端證書身份驗證,其實沒有太大的變化。就是使用證書來驗證客戶端的有效性,合法性。

   (1)服務器需要一個證明服務器身份和有效的可用於TLS傳輸層安全的 X.509 證書,並且客戶端必須信任此服務器證書。

   (2)客戶端提交證書的方式與傳輸安全之證書驗證方式一樣,服務器端需要提供證書,但是不需要httpcfg.exe設置。

   (3)初始協商需要服務器證書來建立TLS連接,協商完畢以後,建立共享安全上下文,這裏使用商定的加密算法對SOAP消息進行加密和簽名。

   (4)如果你啓用協商,而不把服務器證書在客戶端設置信任,導入信任的辦法機構,會出現SOAP安全協商失敗的異常。

   (5)這裏客戶端調用WCF服務以前要提供提供了有效的證書,和Transport安全模式的證書驗證方式類似。差別只是在於安全機制,前者使用的是HTTPS來保證通信安全,後者採用TLS。相同的地方都是在建立連接之前進行客戶端證書身份驗證。

   (6)參考代碼: 

Tag標籤: WCF分佈式安全開發實踐,Message,證書驗證,消息安全模式之Certificate身份驗證

 

/Files/frank_xl/8.1.WCFServiceSecurityDemoFrankXuLei_Message_Certificate_WSHttpBinding.rar

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章