[C#.NET][WCF] wsHttpBinding @self-host 的安全性-使用 SSL

  • 6010
  • 0
  • WCF
  • 2019-04-30

[C#.NET][WCF] wsHttpBinding @self-host 的安全性–使用 SSL

https也是WCF所提供的一種傳輸模式,為了實作它費了我好多的時間,接下來就來分享我實作的過程

Step1.準備憑證

在Visual Studio Command Prompt (2010)輸入:

makecert -pe -n CN=WCFRoot -ss Root -sr LocalMachine -a sha1 -sky signature
makecert.exe -sr LocalMachine -ss My -a sha1 -n CN=WCFServer -sky exchange -pe -is Root -ir LocalMachine -in WCFRoot

 

Step2.設定WcfServiceLibrary的App.Config

image

 

image

 

image

 

image

 

image

 

image

 


<?xml version="1.0"?> 
<configuration> 
  <system.serviceModel> 
    <services> 
      <service behaviorConfiguration="EndpointBehavior.Config" name="WcfServiceLibrary.Service"> 
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding.Config" 
          contract="WcfServiceLibrary.IService"> 
          <identity> 
            <dns value="localhost" /> 
          </identity> 
        </endpoint> 
        <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"> 
          <identity> 
            <dns value="" /> 
          </identity> 
        </endpoint> 
        <host> 
          <baseAddresses> 
            <add baseAddress="https://localhost:168" /> 
          </baseAddresses> 
        </host> 
      </service> 
    </services> 
    <behaviors> 
      <serviceBehaviors> 
        <behavior name="EndpointBehavior.Config"> 
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" /> 
          <serviceDebug includeExceptionDetailInFaults="false" /> 
        </behavior> 
      </serviceBehaviors> 
    </behaviors> 
    <bindings> 
      <wsHttpBinding> 
        <binding name="wsHttpBinding.Config"> 
          <security mode="Transport"> 
            <transport clientCredentialType="None" /> 
            <message clientCredentialType="None" negotiateServiceCredential="true" /> 
          </security> 
        </binding> 
      </wsHttpBinding> 
    </bindings>

  </system.serviceModel>

</configuration>

Step3.利用 HttpConfig.exe,配置 SSL 憑證

由此下載 http://www.stevestechspot.com/

image

 

配置步驟如下:

先取得組件的GUID碼

image

 

image

 

填寫相關資訊

IP:0.0.0.0

Port:168

GUID:6df35b6e-860f-4bcc-89ce-096f20ead372

選擇憑證

image

 

設定完成後套用

image

 

Step4.在WcfServiceLibrary專案按下F5

Step5.新增一個Winform的Client專案,命名為WcfServiceClient

並加入遠端的 WCF Server 參考,這裡就是用 https 的傳輸協議

image

 

image

 

image

 

設計UI

image

 

加入以下程式碼

 


private ServiceClient _client = new ServiceClient();

private void button_GetResult_Click(object sender, EventArgs e)
{
    this.button_GetResult.Enabled = false;
    string result = "";
    try
    {
        result = this._client.SayHello(textBox_UserName.Text);
        MessageBox.Show(result);
    }
    catch (TimeoutException exception)
    {
        var msg = string.Format(exception.Message);
        this._client.Abort();
        MessageBox.Show(msg);
    }
    catch (CommunicationException exception)
    {
        var msg = string.Format(exception.Message);
        this._client.Abort();
        MessageBox.Show(msg);
    }
    this.button_GetResult.Enabled = true;
}

Client的App.Config如下

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IService">
          <security mode="Transport">
            <transport clientCredentialType="None" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://遠端位置:168/" binding="wsHttpBinding"
          bindingConfiguration="WSHttpBinding_IService" contract="WcfServiceLibrary.IService"
          name="WSHttpBinding_IService">
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

 

 

執行Client端的Get Result按鈕,會出現以下訊息,這個訊息很有可能代表著憑證問題;若換成被MS認可的CA中心所發行的憑證,可能就會沒有此問題,因為在此我們所用的憑證是根憑證所產生,不知是這樣所造成的原因?

image

 

所以在Client我們用以下方法處理回傳遠端Server的憑證永遠是對的:


private void SetCertificatePolicy()
{
    ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate;
}

/// <summary>
/// Remotes the certificate validate.
/// </summary>
private bool RemoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
{
    // trust any certificate!!!
    System.Console.WriteLine("Warning, trust any certificate");
    return true;
}

然後把SetCertificatePolicy方法寫在Client的建構函式即可。

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo