WCF雙工通訊+身份認證
阿新 • • 發佈:2019-02-10
證書
以管理員身份開啟VS開發人員命令提示符工具 然後輸入如下字串 makecert -sr localmachine -ssRoot -n CN=GreenWhale -sky exchange -pe -r。 回車返回Success即可。 然後開啟“C:\Windows\System32\en-US\certlm.msc” Zh-CN也可 “C:\Windows\System32\zh-CN\certlm.msc” 別打錯了不是這個“certmgr.msc” 然後就可以看到證書了,匯出證書,軟體釋出後讓客戶端安裝此證書即可。服務端
服務端回撥介面:
using[OperationContract] IPEndPointServerRequestClientIP();
[OperationContract] voidServerSayMsg(string text); } }
服務介面
usingSystem; usingSystem.ServiceModel; namespaceWcfService1WCF 服務端程式碼實現
請注意,服務端回撥客戶端時 客戶端的連結必須沒有斷開,斷開了就無法回調了,
身份認證
實現身份認證需要服務端繼承System.IdentityModel.Selectors.UserNamePasswordValidator類。同理需要引用System.IdentityModel.Dll;
namespaceWcfService1 { /// <summary> /// WCF身份認證 /// </summary> publicclassWCFValidator : System.IdentityModel.Selectors.UserNamePasswordValidator { /// <summary> /// 身份及密碼驗證 /// </summary> /// <paramname="userName"></param> /// <paramname="password"></param> publicoverridevoid Validate(string userName,string password) { if (userName=="1234"&&password=="1234")//身份驗證不過則報錯,過了就過了。 { } else { thrownewSystem.IdentityModel.Tokens.SecurityTokenException("Unknown Username or Password"); } } } }Web配置檔案
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilationdebug="true"targetFramework="4.0"/>
</system.web>
<system.serviceModel>
<services>
<servicename="WcfService1.ClientCallServer">
<endpointaddress=""binding="wsDualHttpBinding"bindingConfiguration="NewBinding0"
contract="WcfService1.IClientCallServer">
</endpoint>
</service>
</services>
<bindings>
<wsDualHttpBinding>
<bindingname="NewBinding0">
<securitymode="Message"><--訊息加密->
<messageclientCredentialType="UserName"/>
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceCredentials>
<--findValue
公司名稱=GreenWhale,storeLocation==儲存位置本機,儲存位置:Root(根證書區)->
<serviceCertificatefindValue="CN=GreenWhale"x509FindType="FindBySubjectDistinguishedName"storeLocation="LocalMachine"storeName="Root"></serviceCertificate>
<clientCertificate>
<authenticationcertificateValidationMode="None"></authentication>
</clientCertificate>
<---customUserNamePasswordValidatorType,先放動態庫的名稱空間+類名,然後時逗號然後是dll名稱,我這裡時WcfService1--->
<userNameAuthenticationuserNamePasswordValidationMode="Custom"includeWindowsGroups="false"customUserNamePasswordValidatorType="WcfService1.WCFValidator,WcfService1"></userNameAuthentication>
</serviceCredentials>
<!-- 為避免洩漏元資料資訊,請在部署前將以下值設定為 false -->
<serviceMetadatahttpGetEnabled="true"/>
<!-- 要接收故障異常詳細資訊以進行除錯,請將以下值設定為 true。在部署前設定為 false 以避免洩漏異常資訊 -->
<serviceDebugincludeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironmentaspNetCompatibilityEnabled="false"
multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modulesrunAllManagedModulesForAllRequests="true"/>
<!--
若要在除錯過程中瀏覽 Web 應用程式根目錄,請將下面的值設定為 True。
在部署之前將該值設定為 False 可避免洩露 Web 應用程式資料夾資訊。
-->
<directoryBrowseenabled="true"/>
</system.webServer>
</configuration>
客戶端
客戶端很簡單,首先引用WCF服務,然後在連線時輸入對應的賬號和密碼即可。
usingSystem; usingSystem.Collections.Generic; usingSystem.ComponentModel; usingSystem.Data; usingSystem.Drawing; usingSystem.Linq; usingSystem.Net; usingSystem.ServiceModel; usingSystem.Text; usingSystem.Windows.Forms; usingSystem.Xml; usingWindowsFormsApp1.Service; namespaceWindowsFormsApp1 { publicpartialclass Form1 :Form, IClientCallServerCallback { publicForm1() { InitializeComponent(); context=newInstanceContext(this); client=newClientCallServerClient(context); } publicIPEndPointServerRequestClientIP() { thrownewNotImplementedException(); } InstanceContext context; publicvoidServerSayMsg(string text) { MessageBox.Show(text); } ClientCallServerClient client; privatevoidbutton1_Click(object sender,EventArgs e) { // certificateValidationMode client.ClientCredentials.UserName.UserName="1234"; client.ClientCredentials.UserName.Password="1234"; client.ClientSayToServer("Fuck"); } } }