最近到了新公司,leader讓我研究一下WCF的傳輸安全機制。之前也作過WCF的應用,可是不多涉及安全方面的東西。因此,花了三天的時間研究了一下如何在WCF的應用程序中配置安全。在這個系列文章中,我會將個人一些心得分享給你們,但願對你們有所幫助。html
我所作的研究主要是使用UserName的驗證方式,對請求進行驗證,本文主要介紹使用basicHttpBinding進行驗證,後續兩篇文章中將針對wsHttpBinding介紹使用http方式驗證以及https(SSL)方式驗證。安全
首先,想跟你們說明,這幾篇帖子,個人重點在於如何配置WCF應用程序,使你的WCF程序可以使用UserName的安全驗證;而不在於如何創建WCF應用程序,若是你們想了解關於創建WCF應用程序的相關知識,請參考MSDN相關文檔。app
Let's go!ide
我將個人應用程序分爲服務端與訪問端,下面讓咱們分別看服務端與客戶端。post
1. 服務端ui
(1) 建立CustomUserNameValidatorurl
CustomUserNameValidator從UserNamePasswordValidator類繼承,而且須要實現抽象方法Validate,能夠在其中實現用戶名密碼驗證邏輯,若是驗證不成功,拋出異常。spa
1 public class CustomUserNameValidator : UserNamePasswordValidator 2 { 3 private const string USERNAME_ELEMENT_NAME = "userName"; 4 5 private const string PASSWORD_ELEMENT_NAME = "password"; 6 7 private const string FAULT_EXCEPTION_MESSAGE = "UserName or Password is incorrect!"; 8 9 public override void Validate(string userName, string password) 10 { 11 Guarder.Guard.ArgumentNotNull(userName) 12 .ArgumentNotNull(password); 13 var validateUserName = ConfigurationManager.AppSettings[USERNAME_ELEMENT_NAME]; 14 var validatePassword = ConfigurationManager.AppSettings[PASSWORD_ELEMENT_NAME]; 15 var validateCondition = userName.Equals(validateUserName) && password.Equals(validatePassword); 16 if (!validateCondition) 17 { 18 throw new FaultException(FAULT_EXCEPTION_MESSAGE); 19 } 20 } 21 }
(2) 完成服務端配置文件code
服務端配置文件:xml
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <startup> 4 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 5 </startup> 6 <system.serviceModel> 7 <behaviors> 8 <serviceBehaviors> 9 <behavior name="customBehavior"> 10 <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /> 11 <serviceDebug includeExceptionDetailInFaults="true" /> 12 <serviceCredentials> 13 <userNameAuthentication 14 userNamePasswordValidationMode="Custom" 15 customUserNamePasswordValidatorType="EmployeesHost.CustomUserNameValidator, EmployeesHost"/> 16 </serviceCredentials> 17 </behavior> 18 </serviceBehaviors> 19 </behaviors> 20 <bindings > 21 <basicHttpBinding> 22 <binding name="EmployeeQueryBinding_BasicHttp"> 23 <security mode="TransportCredentialOnly"> 24 <transport clientCredentialType="Basic"/> 25 </security> 26 </binding> 27 </basicHttpBinding> 28 </bindings> 29 <services> 30 <service name="EmployeesHost.EmployeesQueryService" behaviorConfiguration="customBehavior"> 31 <!--For basic http binding endpoint--> 32 <endpoint address="http://127.0.0.1:12215/EmployeeQuery" binding="basicHttpBinding" 33 bindingConfiguration="EmployeeQueryBinding_BasicHttp" 34 contract="EmployeesHost.IEmployeesQueryService"> 35 <identity> 36 <dns value="localhost" /> 37 </identity> 38 </endpoint> 39 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 40 <host> 41 <baseAddresses> 42 <add baseAddress="http://127.0.0.1:8733/Design_Time_Addresses/EmployeesHost/EmployeesQueryService/" /> 43 </baseAddresses> 44 </host> 45 </service> 46 </services> 47 </system.serviceModel> 48 <appSettings> 49 <add key="userName" value="username"/> 50 <add key="password" value="password"/> 51 </appSettings> 52 </configuration>
須要注意的是,serviceCredentials節點中須要按照上面文件中的寫法。binding節點中也須要嚴格按照上面文件中所寫。、
(3) 完成ServiceHost啓動
啓動ServiceHost代碼:
1 static void Main(string[] args) 2 { 3 var host = new ServiceHost(typeof(EmployeesQueryService)); 4 host.Open(); 6 Console.WriteLine("Service Host opened, press <s> to stop..."); 7 var key = Console.ReadKey(); 8 if (key.Key == ConsoleKey.S) 9 { 10 host.Close(); 11 } 12 Console.WriteLine("Press any key to quit..."); 13 Console.ReadKey(); 14 }
2. 客戶端
(1) 客戶端配置文件:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <startup> 4 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 5 </startup> 6 <system.serviceModel> 7 <bindings> 8 <basicHttpBinding> 9 <binding name="DefaultBinding_IEmployeesQueryService"> 10 <security mode="TransportCredentialOnly"> 11 <transport clientCredentialType="Basic"/> 12 </security> 13 </binding> 14 </basicHttpBinding> 15 </bindings> 16 <client> 17 <!--For basic http binding endpoint--> 18 <endpoint address="http://127.0.0.1:12215/EmployeeQuery/" 19 binding="basicHttpBinding" bindingConfiguration="DefaultBinding_IEmployeesQueryService" 20 contract="IEmployeesQueryService" name="DefaultBinding_IEmployeesQueryService_IEmployeesQueryService" /> 21 </client> 22 </system.serviceModel> 23 <appSettings> 24 <add key="userName" value="username"/> 25 <add key="password" value="password"/> 26 </appSettings> 27 </configuration>
注意,客戶端配置文件中的binding節點,須要與服務端的binding節點寫法相同。
(2) 客戶端調用代碼
1 var userName = ConfigurationManager.AppSettings[USERNAME_ELEMENT_NAME]; 2var password = ConfigurationManager.AppSettings[PASSWORD_ELEMENT_NAME]; 3 mProxy.ClientCredentials.UserName.UserName = userName; 4 mProxy.ClientCredentials.UserName.Password = password; 5 var data = mProxy.GetData();
OK,大功告成,運行,ok。