[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
<?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/
配置步驟如下:
先取得組件的GUID碼
填寫相關資訊
IP:0.0.0.0
Port:168
GUID:6df35b6e-860f-4bcc-89ce-096f20ead372
選擇憑證
設定完成後套用
Step4.在WcfServiceLibrary專案按下F5
Step5.新增一個Winform的Client專案,命名為WcfServiceClient
並加入遠端的 WCF Server 參考,這裡就是用 https 的傳輸協議
設計UI
加入以下程式碼
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中心所發行的憑證,可能就會沒有此問題,因為在此我們所用的憑證是根憑證所產生,不知是這樣所造成的原因?
所以在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