【WCF--初入江湖】11 安全
11 安全
前言
【1】傳輸安全 傳輸安全模式 傳輸安全與綁定協(xié)議 【2】身份驗(yàn)證 身份驗(yàn)證分類 證書 示例:傳輸安全匿名客戶端證書的使用?
1. 傳輸安全
? ?
保證信息在傳輸過程中的安全.傳輸安全是身份驗(yàn)證和授權(quán)的前提。傳輸安全模式:
None:關(guān)閉了傳輸安全的功能 transport security:對通道上所有的通信加密,除了接收者外,沒有任何一方可以看見消息的內(nèi)容。 message security:只是對消息的本身進(jìn)行加密而不是對傳輸進(jìn)行加密。 Mixed:在實(shí)現(xiàn)完整性和機(jī)密性以及服務(wù)端身份驗(yàn)證時(shí)采用的是Transport Security模式,而在保護(hù)客戶端安全憑證的安全時(shí)采用了Message Security模式。 Both:同是使用Transport模式和Message模式,就是傳輸時(shí)安全的,傳輸?shù)南⒁彩墙?jīng)過加密的.?
? ? ? 配置
傳輸安全模式是在綁定中配置的.
?
binding與傳輸安全模式
傳輸安全模式與各種binding是一個組合的關(guān)系,并不是每種binding都能應(yīng)用所有的傳輸安全模式,
所有WCF的綁定默認(rèn)都是安全的,只有BasicHttpBinding默認(rèn)是非安全的
| 名稱 | None | Transport | Message | Mixed | Both |
| BasicHttpBinding | Yes(默認(rèn)) | Yes | Yes | Yes | No |
| NetTcpBinding | Yes | Yes(默認(rèn)) | Yes | Yes | No |
| NetNamedPipeBinding | Yes | Yes(默認(rèn)) | No | No | No |
| WSHttpBinding | Yes | Yes | Yes(默認(rèn)) | Yes | No |
| WSDualHttpBinding | Yes | No | Yes(默認(rèn)) | No | No |
| NetMsmqBinding | Yes | Yes(默認(rèn)) | Yes | No | Yes |
? ? 配置文件的形式:
<bindings><netTcpBinding><binding name="tcpBinding"><security mode="Transport"><transport clientCredentialType="Windows“ protectionLevel="EncryptAndSign"/></security></binding></netTcpBinding> </bindings>編程方式實(shí)現(xiàn):
NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport);或者
NetTcpBinding binding1 = new NetTcpBinding(); binding1.Security.Mode = SecurityMode.Transport;
?
2. 身份驗(yàn)證
?
2.1 Transport模式的身份驗(yàn)證
?
在Transport模式下,身份驗(yàn)證與binding的關(guān)系
????
| ? 名稱 | None | Windows | UserName | Certificate |
| BasicHttpBinding | Yes(默認(rèn)) | Yes | Yes | Yes |
| NetTcpBinding | Yes | Yes(默認(rèn)) | No | Yes |
| NetNamedPipeBinding | No | Yes(默認(rèn)) | No | No |
| WSHttpBinding | Yes | Yes(默認(rèn)) | Yes | Yes |
| WSDualHttpBinding | ? | ? | ? | ? |
| NetMsmqBinding | Yes | Yes(默認(rèn)) | No | Yes |
所有的局域網(wǎng)綁定都支持Windows方式的身份驗(yàn)證
NetTcpBinding在Transport模式下不支持UserName身份驗(yàn)證模式
wsDualHttpBinding不支持Transport傳輸安全模式的
?
?2.2?Message模式的身份驗(yàn)證
? 在Message傳輸安全模式下Binding與身份驗(yàn)證
?
| ? 名稱 | None | Windows | UserName | Certificate | IssuedToken |
| BasicHttpBinding | No | No | No | Yes | No |
| NetTcpBinding | Yes | Yes(默認(rèn)) | Yes | Yes | Yes |
| NetNamedPipeBinding | ? | ? | ? | ? | ? |
| WSHttpBinding | Yes | Yes(默認(rèn)) | Yes | Yes | Yes |
| WSDualHttpBinding | Yes | Yes(默認(rèn)) | Yes | Yes | Yes |
| NetMsmqBinding | Yes | Yes(默認(rèn)) | Yes | Yes | Yes |
?
除了BasicHttpBinding和NetNamedPipeBinding以外,其他的模式默認(rèn)都是用Windows憑證
?
示例:
<?xml version="1.0" encoding="utf-8" ?> <configuration><system.web><compilation debug="true" /></system.web><system.serviceModel><bindings><wsHttpBinding><binding name="wsHttpBinding_Security"><security mode="Transport"><transport clientCredentialType="None"/><!--啟用傳輸安全,身份認(rèn)證是匿名的--></security></binding></wsHttpBinding></bindings><services><service name="Keasy5.WCF.Security.Translation.Service1"><host><baseAddresses><!--Http和SSL 兩者要成對--><add baseAddress = "http://localhost:8733/Design_Time_Addresses/Keasy5.WCF.Security.Translation/Security/" /><add baseAddress = "https://localhost:8833/Design_Time_Addresses/Keasy5.WCF.Security.Translation/Security/" /></baseAddresses></host><endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding_Security"contract="Keasy5.WCF.Security.Translation.IService1"><identity><dns value="localhost"/></identity></endpoint><endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/></service></services><behaviors><serviceBehaviors><behavior><serviceMetadata httpGetEnabled="True"/><serviceDebug includeExceptionDetailInFaults="False" /></behavior></serviceBehaviors></behaviors></system.serviceModel></configuration> View Code?
?其中:
<bindings><wsHttpBinding><binding name="wsHttpBinding_Security"><security mode="Transport"><transport clientCredentialType="None"/><!--啟用傳輸安全,身份認(rèn)證是匿名的--></security></binding></wsHttpBinding></bindings><services><service name="Keasy5.WCF.Security.Translation.Service1"><host><baseAddresses><add baseAddress = "http://localhost:8733/Design_Time_Addresses/Keasy5.WCF.Security.Translation/Security/" /><add baseAddress = "https://localhost:8833/Design_Time_Addresses/Keasy5.WCF.Security.Translation/Security/" /></baseAddresses></host><endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding_Security"contract="Keasy5.WCF.Security.Translation.IService1">? 注意:如果啟用了傳輸安全,即:<security mode="Transport">,那么就必須提供:https開頭的基地址
:
<add baseAddress = "http://localhost:8733/Design_Time_Addresses/Keasy5.WCF.Security.Translation/Security/" /><add baseAddress = "https://localhost:8833/Design_Time_Addresses/Keasy5.WCF.Security.Translation/Security/" />否則WCF服務(wù)拋出異常:
下面是我們注釋掉:https:基地址后,
?
<baseAddresses><add baseAddress = "http://localhost:8733/Design_Time_Addresses/Keasy5.WCF.Security.Translation/Security/" /><!--<add baseAddress = "https://localhost:8833/Design_Time_Addresses/Keasy5.WCF.Security.Translation/Security/" />--></baseAddresses>拋出異常
System.InvalidOperationException: 找不到具有綁定 WSHttpBinding 的終結(jié)點(diǎn)的與方案 https 匹配的基址。注冊的基址方案是 [http]。?
設(shè)置完上述的配置后,客戶端(這里使用VS對WCF服務(wù)庫內(nèi)置的【W(wǎng)CF測試客戶端】)調(diào)用時(shí)發(fā)生異常:
對 https://localhost:8833/Design_Time_Addresses/Keasy5.WCF.Security.Translation/Security/ 執(zhí)行 HTTP 請求時(shí)發(fā)生錯誤。這可能是由于在使用 HTTPS 的情況下未使用 HTTP.SYS 正確配置服務(wù)器證書造成的。這還可能是由于客戶端和服務(wù)器之間的安全綁定不匹配所致。這是因?yàn)榕渲弥?#xff0c;我們啟用了傳輸安全,但沒有提供證書。
<security mode="Transport">? ? ? ? ? 啟用了傳輸安全,就必須使用證書。如何提供證書,請看下一節(jié):3.?證書與傳輸安全。
? ??
3.?證書與傳輸安全
?
? 3.1 傳輸安全必須要使用證書
SSL安全套接字層是一個數(shù)據(jù)傳輸加密機(jī)制,它可以確保在客戶機(jī)與服務(wù)器之間傳輸?shù)臄?shù)據(jù)仍然是安全與隱密的。 傳輸安全 (HTTPS) 確保保密性和完整性。 SSL 廣泛用于 Internet 中,以便向客戶端證明服務(wù)的身份,并且隨后向通道提供保密性(加密)。 證書就相當(dāng)于是身份證一樣,客戶端可以不進(jìn)行身份驗(yàn)證。但是要有一個服務(wù)器證書來保證客戶端和服務(wù)器之間能夠建立SSL安全套接字連接。? ? ? 3.2?證書制作
?
【1】使用Makecert命令創(chuàng)建證書 Makecert證書創(chuàng)建工具生成的 X.509 證書。 它創(chuàng)建用于數(shù)字簽名的公鑰和私鑰對,并將其存儲在證書文件中。 此工具還將密鑰對與指定發(fā)行者的名稱相關(guān)聯(lián),并創(chuàng)建一個 X.509 證書,該證書將用戶指定的名稱綁定到密鑰對的公共部分。? 步驟:
第一步:創(chuàng)建證書
打開Vs的【VS2013 開發(fā)人員命令提示】,輸入如下命令
makecert -sr localmachine -ss My -n CN=WCFServerPK -sky exchange -pe -r? ? ? 其中,
-sr localmachine -sr指定證書的存放位置,localmachine 指是存儲在本機(jī)上 ,也可以是current,存放到當(dāng)前用戶 -ss My -ss指定證書存儲的目錄,My指【個人】這個目錄,如果用【Hello】,則創(chuàng)建一個【Hello】目錄 -n CN=WCFServerPK -n 指定證書的名稱,cn=前綴(Common Name),WCFServerPK 是證書的名稱第二步:查看證書
打開【命令】(或者Win+R),輸入mmc,確定
再選【計(jì)算機(jī)賬戶(C)】選項(xiàng),添加控制臺節(jié)點(diǎn)。
?
第三步:導(dǎo)出證書:
右鍵證書--所有任務(wù)--導(dǎo)出,在導(dǎo)出過程中有一步是要求輸入密碼(這里設(shè)置為123456),然后輸入證書的名稱WCFServicePK,最后導(dǎo)出
? ? ? WCFServicePK.pfx文件。
第四步:在客戶端上安裝證書。
在客戶端所在的計(jì)算機(jī)上,安裝在第一步中打開的【控制臺】,在【證書(本地計(jì)算機(jī))】--【受信任人】--【證書】右鍵--【所有任務(wù)】--
【導(dǎo)入】,把第三步導(dǎo)出的證書導(dǎo)入,下面的過程證有一步要求輸入證書密碼(改密碼就是第三步設(shè)置的證書密碼123456)。
也可以為其他地方(如:受信任的根證書頒發(fā)機(jī)構(gòu))導(dǎo)入證書WCFServicePK.pfx。
?
第五步:設(shè)置SSL證書
? 需要一個工具:httpcfg.下載地址:
? ? ? ? ??鏈接: http://pan.baidu.com/s/1c04DMSg 密碼: me2p
? ? ? ? ? 下載該工具后,把它解壓并保存到一個目錄下,本例使用:D:/
? ? ? ? ? ?打開命名(win+R),輸入cmd,切換到D:目錄
? ? ? ? ? ?查看SSL配置:
httpcfg query ssl? ? 設(shè)置SSL配置:
在第二步中打開的【控制臺】界面的右邊列表中,選擇WCFServicePK,雙擊打開證書(或者右鍵--打開),在彈出框中,
選擇【詳細(xì)信息】--選擇【指紋】,復(fù)制這些字符串,本例中這些字符串為:
832420b5499bf8eca2c924e63fb9b6192201d034
? ? ?然后在輸入如下命令:
httpcfg set ssl -i 0.0.0.0:8833 -h 832420b5499bf8eca2c924e63fb9b6192201d034?
? ? ? ? 這樣,使得證書和端口8833進(jìn)行關(guān)聯(lián),其中:
【1】832420b5499bf8eca2c924e63fb9b6192201d034 就是證書的指紋。
? ? ? ?? 【2】0.0.0.0:8833 ? ? ? ? ?8833是端口,這就是配置WCF服務(wù)時(shí)指定的Https基地址的端口
<add baseAddress = "https://localhost:8833/Design_Time_Addresses/Keasy5.WCF.Security.Translation/Security/" />?
如果要刪除SSL配置,可以輸入:
httpcfg delete ssl -i 0.0.0.0:8833 -h 832420b5499bf8eca2c924e63fb9b6192201d034? ? ?
第六步:服務(wù)端配置證書:
<services><service </service></services><behaviors><serviceBehaviors><behavior><serviceMetadata httpGetEnabled="True"/><serviceDebug includeExceptionDetailInFaults="False" /><serviceCredentials><serviceCertificate storeLocation="LocalMachine"x509FindType="FindBySubjectName"findValue="WCFServerPK" storeName="My"/></serviceCredentials></behavior></serviceBehaviors></behaviors>?
? ? ? 其中,findValue的值是:3.2 第一步中 “-n CN=WCFServerPK"中指定的值
? ? ? 這里新建一個控制臺程序作為宿主:
? ? ? 宿主的配置app.config:
<?xml version="1.0" encoding="utf-8" ?> <configuration><system.web><compilation debug="true" /></system.web><system.serviceModel><bindings><wsHttpBinding><binding name="wsHttpBinding_Security"><security mode="Transport"><transport clientCredentialType="None"/><!--啟用傳輸安全,身份認(rèn)證是匿名的--></security></binding></wsHttpBinding></bindings><services><service name="Keasy5.WCF.Security.Translation.Service1"><host><baseAddresses><add baseAddress = "http://localhost:8733/Keasy5.WCF.Security.Translation/Security/" /><add baseAddress = "https://localhost:8833/Keasy5.WCF.Security.Translation/Security/" /></baseAddresses></host><endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding_Security"contract="Keasy5.WCF.Security.Translation.IService1"><identity><dns value="localhost"/></identity></endpoint><endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/></service></services><behaviors><serviceBehaviors><behavior><serviceMetadata httpGetEnabled="True"/><serviceDebug includeExceptionDetailInFaults="False" /><serviceCredentials><serviceCertificate storeLocation="LocalMachine"x509FindType="FindBySubjectName"findValue="WCFServerPK" storeName="My"/></serviceCredentials></behavior></serviceBehaviors></behaviors></system.serviceModel></configuration> View Code
宿主代碼:
namespace Keasy5.WCF.Security.Translation.Host {class Program{static void Main(string[] args){using (ServiceHost serviceHost = new ServiceHost(typeof(Service1))){serviceHost.Open();Console.WriteLine("服務(wù)已啟動");Console.ReadKey();}}} }?
?????? 第七步:客戶端調(diào)用服務(wù):
新建一個控制臺項(xiàng)目,然后引用服務(wù),輸入如下地址:
https://localhost:8833/Keasy5.WCF.Security.Translation/Security/
然后點(diǎn)擊【轉(zhuǎn)到】,這時(shí)候,彈出一個對話框【安全報(bào)警,說明SSL證書配置成功。
客戶端自動生成的app.cong配置:
<?xml version="1.0" encoding="utf-8" ?> <configuration><system.serviceModel><bindings><wsHttpBinding><binding name="WSHttpBinding_IService1"><security mode="Transport"><transport clientCredentialType="None" /></security></binding></wsHttpBinding></bindings><client><endpoint address="https://localhost:8833/Keasy5.WCF.Security.Translation/Security/"binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"contract="ServiceReference1.IService1" name="WSHttpBinding_IService1"><identity><dns value="localhost" /></identity></endpoint></client></system.serviceModel> </configuration>
調(diào)用服務(wù)方法:
namespace Keasy5.WCF.Security.Translation.Client {class Program{static void Main(string[] args){Service1Client service1Client = new Service1Client();try{string message = service1Client.GetData("Https傳輸安全");Console.WriteLine(message);}catch (Exception e){Console.WriteLine(e.Message);}Console.ReadKey();}} }先啟動宿主,后啟動客戶端;
????? 這時(shí),客戶端拋出如下異常:
無法為 SSL/TLS 安全通道與頒發(fā)機(jī)構(gòu)“l(fā)ocalhost:8833”建立信任關(guān)系。???? 客戶端調(diào)用還需要添加代碼,強(qiáng)制信任證書:
namespace Keasy5.WCF.Security.Translation.Client {class Program{static void Main(string[] args){Service1Client service1Client = new Service1Client();//強(qiáng)制信任證書ServicePointManager.ServerCertificateValidationCallback +=ServerCertificateValidationCallback;try{string message = service1Client.GetData("Https傳輸安全");Console.WriteLine(message);}catch (Exception e){Console.WriteLine(e.Message);}Console.ReadKey();}private static bool ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors){return true;}} }
?
?
?源碼下載:
?鏈接: http://pan.baidu.com/s/1eQh9iq2 密碼: 4ogd
?
? 案例總結(jié)
WSHttpBinding 綁定,匿名客戶端(none)的傳輸安全模式(Transport)
? ?1、制作證書
?? 2、SSL證書設(shè)置
?? 3、服務(wù)端配置
?? 4、客戶端配置
?
5. 身份認(rèn)證
【1】身份驗(yàn)證類型(transport客戶端憑證類型)
1.None 2.Basic 3.Digest 4.HTLM 5.Windows 6.Certificate <bindings><netTcpBinding><binding name=""><security mode="Transport"><transport clientCredentialType="Windows"/></security></binding></netTcpBinding></bindings>
【2】身份驗(yàn)證類型(Message客戶端憑證類型)
<bindings><wsHttpBinding><binding name=""><security mode="Message"><message clientCredentialType="UserName"/></security></binding></wsHttpBinding></bindings>
?
5.1 示例:Basic身份驗(yàn)證
傳輸安全模式之基本身份驗(yàn)證:? 傳輸安全模式之基本身份驗(yàn)證需要服務(wù)器需要一個有效的可用于安全套接字層 (SSL) 的 X.509 證書,
并且客戶端必須信任此服務(wù)器證書。如果不信任此證書會導(dǎo)致建立SSL傳輸連接失敗,因?yàn)榭蛻舳藭J(rèn)為服務(wù)端是一個非法的服務(wù)端,因而建立SSL安全套接層失敗。
1.身份驗(yàn)證(服務(wù)器):提供證書,(使用 HTTPS) 2.身份驗(yàn)證(客戶端):提供用戶名/密碼?
客戶端建立SSL安全套接層以后,會使用協(xié)定的密碼對消息簽名,客戶端使用證書加密數(shù)據(jù),服務(wù)端使用證書解密數(shù)據(jù),保證數(shù)據(jù)的安全和機(jī)密性。
步驟:
? 1、制作證書
? 2、SSL證書設(shè)置
? 3、服務(wù)端配置
? ????? ???? 傳輸模式設(shè)置
?????????????????????? 證書使用
? 4、客戶端配置(用戶名和密碼)
第一步--第二步:與上一節(jié)相同。
第三步:服務(wù)端的配置:
<?xml version="1.0" encoding="utf-8" ?> <configuration><system.web><compilation debug="true" /></system.web><system.serviceModel><bindings><wsHttpBinding><binding name="wsHttpBinding_Transport"><security mode="Transport"><transport clientCredentialType="Basic"/><!--Basics是用戶名和密碼的身份認(rèn)證模式--></security></binding></wsHttpBinding></bindings><services><service name="Keasy5.WCF.Credential.Service.Service1"><host><baseAddresses><add baseAddress = "https://localhost:8833/Keasy5.WCF.Credential.Service/Service1/" /></baseAddresses></host><endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding_Transport"contract="Keasy5.WCF.Credential.Service.IService1"><identity><dns value="localhost"/></identity></endpoint><endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/></service></services><behaviors><serviceBehaviors><behavior><serviceMetadata httpsGetEnabled="True"/><serviceDebug includeExceptionDetailInFaults="False" /><serviceCredentials><serviceCertificate storeLocation="LocalMachine"storeName="My"x509FindType="FindBySubjectName"findValue="WCFServerPK"/></serviceCredentials></behavior></serviceBehaviors></behaviors></system.serviceModel></configuration>
?
? 第四步:客戶端調(diào)用服務(wù)
新建客戶端控制臺項(xiàng)目,添加服務(wù)引用,輸入如下地址:
https://localhost:8833/Keasy5.WCF.Credential.Service/Service1/點(diǎn)擊【轉(zhuǎn)到】,彈出一個對話框,要求你輸入賬戶和密碼:
輸入服務(wù)器主機(jī)的密碼后,成功添加服務(wù)器引用。
? ? ? app.config文件自動添加WCF客戶端配置:
<?xml version="1.0" encoding="utf-8" ?> <configuration><system.serviceModel><bindings><wsHttpBinding><binding name="WSHttpBinding_IService1"><security mode="Transport"><transport clientCredentialType="Basic" /></security></binding></wsHttpBinding></bindings><client><endpoint address="https://localhost:8833/Keasy5.WCF.Credential.Service/Service1/"binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"contract="ServiceReference1.IService1" name="WSHttpBinding_IService1"><identity><dns value="localhost" /></identity></endpoint></client></system.serviceModel> </configuration>添加客戶端調(diào)用代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Text; using Keasy5.WCF.Credential.Client.ServiceReference1;namespace Keasy5.WCF.Credential.Client {class Program{static void Main(string[] args){try{ServiceReference1.Service1Client service1 = new Service1Client();ServicePointManager.ServerCertificateValidationCallback += ServerCertificateValidationCallback;string message = service1.GetData(200);Console.WriteLine(message);}catch (Exception e){Console.WriteLine(e.Message);}Console.ReadKey();}private static bool ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors){return true; //強(qiáng)制信任證書 }} }?
如果沒有添加如下代碼,提供服務(wù)器端主機(jī)的用戶名和密碼:
//使用用戶名和密碼進(jìn)行登錄服務(wù)器service1.ClientCredentials.UserName.UserName = "easy5";service1.ClientCredentials.UserName.Password = " ";
就會拋出異常:
未提供用戶名。請?jiān)?ClientCredential 中指定用戶名。? ? 更正客戶端代碼:
namespace Keasy5.WCF.Credential.Client {class Program{static void Main(string[] args){try{ServiceReference1.Service1Client service1 = new Service1Client();//強(qiáng)制信任證書ServicePointManager.ServerCertificateValidationCallback += ServerCertificateValidationCallback;//使用用戶名和密碼進(jìn)行登錄服務(wù)器service1.ClientCredentials.UserName.UserName = "easy5";service1.ClientCredentials.UserName.Password = " ";string message = service1.GetData(200);Console.WriteLine(message);}catch (Exception e){Console.WriteLine(e.Message);}Console.ReadKey();}private static bool ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors){return true; //強(qiáng)制信任證書}} }
?本節(jié)源碼下載:
鏈接: http://pan.baidu.com/s/1hqtauMw 密碼: eh0d
?
5.2 示例:Basic身份驗(yàn)證之自定義身份驗(yàn)證
?
5.1 示例:Basic身份驗(yàn)證 中的身份驗(yàn)證需要客戶端知道服務(wù)器端的密碼,顯然這很不合理,
所以自定義一種驗(yàn)證方式。
? 【1】自定義身份驗(yàn)證配置如下:
<serviceCredentials>。。。。。。
<clientCertificate><authentication certificateValidationMode="None"/></clientCertificate><userNameAuthentication userNamePasswordValidationMode=“Custom”
customUserNamePasswordValidatorType=“命名空間名.自定義驗(yàn)證類名,程序集名"/></serviceCredentials>
注意:
???????????? customUserNamePasswordValidatorType=“命名空間名.自定義驗(yàn)證類名, 程序集名"
????? 必須是:命名空間名.自定義驗(yàn)證類名, 程序集名
????? 否則拋出異常:
未能從程序集“System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中加載類型“Keasy5.WCF.Credential.Service.MyCustomUserNamePasswordValidator”。":"Keasy5.WCF.Credential.Service.MyCustomUserNamePasswordValidator"}
?
【2】自定義驗(yàn)證類
class CustomValidator : UserNamePasswordValidator{public override void Validate(string userName, string password){if (userName != "xxx" || password != "xxx123"){Console.WriteLine("用戶名或密碼出錯!");throw new FaultException("用戶名或密碼出錯!");}}?????? 實(shí)現(xiàn)步驟:
在5.1 示例:Basic身份驗(yàn)證示例的基礎(chǔ)上進(jìn)行修改
第一步:在WCF服務(wù)項(xiàng)目:
添加System.IdentityModel程序集的引用,
添加一個j繼承自UserNamePasswordValidator的類MyCustomUserNamePasswordValidator:
using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.Text; using System.IdentityModel; using System.IdentityModel.Tokens; using System.IdentityModel.Selectors;namespace Keasy5.WCF.Credential.Service {public class MyCustomUserNamePasswordValidator : UserNamePasswordValidator{public override void Validate(string userName, string password){//模擬數(shù)據(jù)庫中的賬號和密碼if (userName.ToLower().Trim() != "admin"&& password.ToLower().Trim() != "admin"){throw new FaultException("用戶名或密碼錯誤");}}} }第二步:在服務(wù)的配置文件app.config中的<serviceCredentials>節(jié)點(diǎn)下添加:
?
<!--添加自定義身份驗(yàn)證--><clientCertificate><authentication certificateValidationMode="None"/></clientCertificate><userNameAuthentication userNamePasswordValidationMode="Custom"customUserNamePasswordValidatorType="Keasy5.WCF.Credential.Service.MyCustomUserNamePasswordValidator,Keasy5.WCF.Credential.Service"/>
?
????? 最終的服務(wù)端配置文件為:
<?xml version="1.0" encoding="utf-8" ?> <configuration><system.web><compilation debug="true" /></system.web><system.serviceModel><bindings><wsHttpBinding><binding name="wsHttpBinding_Transport"><security mode="Transport"><transport clientCredentialType="Basic"/><!--Basics是用戶名和密碼的身份認(rèn)證模式--></security></binding></wsHttpBinding></bindings><services><service name="Keasy5.WCF.Credential.Service.Service1"><host><baseAddresses><add baseAddress = "https://localhost:8833/Keasy5.WCF.Credential.Service/Service1/"/></baseAddresses></host><endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding_Transport"contract="Keasy5.WCF.Credential.Service.IService1"><identity><dns value="localhost"/></identity></endpoint><endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/></service></services><behaviors><serviceBehaviors><behavior><serviceMetadata httpsGetEnabled="True"/><serviceDebug includeExceptionDetailInFaults="False" /><serviceCredentials><serviceCertificate storeLocation="LocalMachine"storeName="My"x509FindType="FindBySubjectName"findValue="WCFServerPK"/><!--添加自定義身份驗(yàn)證--><clientCertificate><authentication certificateValidationMode="None"/></clientCertificate><userNameAuthentication userNamePasswordValidationMode="Custom"customUserNamePasswordValidatorType="Keasy5.WCF.Credential.Service.MyCustomUserNamePasswordValidator,Keasy5.WCF.Credential.Service"/></serviceCredentials></behavior></serviceBehaviors></behaviors></system.serviceModel></configuration> View Code????? 服務(wù)宿主:
using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.Text; using Keasy5.WCF.Credential.Service;namespace Keasy5.WCF.Credential.Host {class Program{static void Main(string[] args){try{using (ServiceHost serviceHost = new ServiceHost(typeof(Service1))){serviceHost.Open();Console.WriteLine("服務(wù)已經(jīng)啟動,按任意鍵關(guān)閉服務(wù)!");Console.ReadKey();}}catch (Exception e){Console.WriteLine(e.Message);Console.ReadKey();}Console.ReadKey();}} }第三步:客戶端引用服務(wù):
?
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Text; using Keasy5.WCF.Credential.Client.ServiceReference1;namespace Keasy5.WCF.Credential.Client {class Program{static void Main(string[] args){try{ServiceReference1.Service1Client service1 = new Service1Client("WSHttpBinding_IService1");//強(qiáng)制信任證書ServicePointManager.ServerCertificateValidationCallback += ServerCertificateValidationCallback;//使用用戶名和密碼進(jìn)行登錄服務(wù)器service1.ClientCredentials.UserName.UserName = "admin";service1.ClientCredentials.UserName.Password = "admin";string message = service1.GetData(200);Console.WriteLine(message);}catch (Exception e){Console.WriteLine(e.Message);}Console.ReadKey();}private static bool ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors){return true; //強(qiáng)制信任證書 }} }?
? 客戶端的配置app.config
<?xml version="1.0" encoding="utf-8" ?> <configuration><system.serviceModel><bindings><wsHttpBinding><binding name="WSHttpBinding_IService1"><security mode="Transport"><transport clientCredentialType="Basic" /></security></binding></wsHttpBinding></bindings><client><endpoint address="https://localhost:8833/Keasy5.WCF.Credential.Service/Service1/"binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"contract="ServiceReference1.IService1" name="WSHttpBinding_IService1"><identity><dns value="localhost" /></identity></endpoint></client></system.serviceModel> </configuration>
?
本節(jié)源碼下載:
鏈接: http://pan.baidu.com/s/18fG9g 密碼: 5t2g
?
?
?
【The End】
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/easy5weikai/p/3825366.html
總結(jié)
以上是生活随笔為你收集整理的【WCF--初入江湖】11 安全的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: md5修改器v1.0
- 下一篇: js-权威指南学习笔记7