日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【转】x.509证书在WCF中的应用(CS篇)

發(fā)布時間:2023/12/4 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】x.509证书在WCF中的应用(CS篇) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

【轉(zhuǎn)自】x.509證書在WCF中的應(yīng)用(CS篇)

?

?

為什么要用x.509證書?
WCF的服務(wù)端和客戶端之間,如 果不作任何安全處理(即服務(wù)端的<security mode="None">),則所有傳輸?shù)南⒁悦魑姆绞綕M天飛,在internet/intranet環(huán)境下無疑是很不安全的,這就是用證書的 目的。(當(dāng)然WCF還有其它安全機(jī)制,比如最常見的UserName方式,但通常每次都要從數(shù)據(jù)庫讀取用戶名/密碼信息進(jìn)行驗證,比較麻煩,開銷也大,個 人覺得還是證書最為方便)--關(guān)于x.509證書

的基本知識,可參見http://www.cnblogs.com/yjmyzz/archive/2008/08/19/1271171.html

大致原理(個人理解,可能不太準(zhǔn)確):
正確設(shè)置服務(wù)端與客戶端證書后,WCF的服務(wù)端啟動時,需要利用服務(wù)端證書驗證,如果驗證通過將正常啟動,否則報異常,同時客戶端調(diào)用服務(wù)端方法時,也需要提供客戶端證書,服務(wù)端接受到客戶端證書后,驗證客戶端證書的有效性,如果通過,則允許客戶端正常調(diào)用。

?

下面將逐步講解如何使用:

1.制作證書

先進(jìn)入到vs2008的命令行狀態(tài),即:
開始-->程序-->Microsoft Visual Studio 2008-->Visual Studio Tools-->Visual Studio 2008 命令提示

鍵入:

makecert?-r?-pe?-n?"CN=MyServer"?-ss?My?-sky?exchange

解釋一下:makecert.exe是一個專門用來制作證書的小工具,上面一行的意思就是制作一個CN=MyServer的服務(wù)器證書,默認(rèn)存儲在CurrentUser"My這個位置,同時這個證書標(biāo)識為可導(dǎo)出。(詳細(xì)的

MakeCert參數(shù)可參見http://msdn.microsoft.com/zh-cn/bfsktky3(vs.80).aspx)

再輸入:

makecert?-r?-pe?-n?"CN=MyClient"?-ss?My?-sky?exchange

生成客戶端證書,證書生成好以后,可以在IE里查看到,IE-->工具-->Internet選項-->內(nèi)容-->證書

同時如何管理已經(jīng)安裝的證書,可參見http://www.cnblogs.com/yjmyzz/archive/2008/08/20/1272128.html

2.wcf服務(wù)端

vs.net2008啟動后,新建一個控制臺應(yīng)用程序-->(右擊)添加-->新建項-->WCF服務(wù)-->命名為MyService.cs-->保存

保存后,系統(tǒng)會自動生成一個接口文件IMyService.cs

二個文件的內(nèi)容如下:
IMyService.cs

using?System;??
using?System.ServiceModel;

namespace?Server
{
????
//?注意:?如果更改此處的接口名稱?"IMyService",也必須更新?App.config?中對?"IMyService"?的引用。
????[ServiceContract]
????
public?interface?IMyService
????{
????????[OperationContract]
????????
string?Test();

????}
}


MyService.cs

using?System;?
using?System.ServiceModel;
namespace?Server
{
????
//?注意:?如果更改此處的類名?"MyService",也必須更新?App.config?中對?"MyService"?的引用。
????public?class?MyService?:?IMyService
????{
????????
public?string?Test()
????????{
????????????Console.WriteLine(
"服務(wù)端輸出:"n"?+?ServiceSecurityContext.Current.PrimaryIdentity.AuthenticationType);
????????????Console.WriteLine(ServiceSecurityContext.Current.PrimaryIdentity.Name);
????????????
return?"服務(wù)端時間:"?+?DateTime.Now.ToString();?
????????}
????}
}

再來新建一個cs文件:CustomX509CertificateValidator.cs
內(nèi)容先貼在下面

using?System;
using?System.Security.Cryptography.X509Certificates;
using?System.IdentityModel.Tokens;
using?System.IdentityModel.Selectors;

namespace?Server
{
????
public?class?CustomX509CertificateValidator?:?X509CertificateValidator
????{
????????
public?override?void?Validate(X509Certificate2?certificate)
????????{
????????????Console.WriteLine(certificate.Subject);
????????????Console.WriteLine(certificate.Thumbprint);?
????????????
if?(certificate.Thumbprint?!=?"3E4D4B64A90810B6CFF9B1DD2390D8C9488747BF")
????????????????
throw?new?SecurityTokenException("Certificate?Validation?Error!");
????????}
????}
}

?

注意:項目必須先添加對System.IdentityModel的引用

解釋一下:
這個文件的用戶是:客戶端要調(diào)用服務(wù)端方法,并提供客戶端證書時,用來驗證客戶端證書的有效性。注意里面的if (certificate.Thumbprint != "3E4D4B64A90810B6CFF9B1DD2390D8C9488747BF")這一句,大家調(diào)試的時候,里面的 3E4D4B64A90810B6CFF9B1DD2390D8C9488747BF要換成你自己的客戶端證書的信息(每一個證書對應(yīng)的這一串字符都是唯 一的),可通過在IE瀏覽器里,查看MyClient證書的詳細(xì)信息得到,見下圖:


同時注意配置文件App.Config,內(nèi)容如下

<?xml?version="1.0"?encoding="utf-8"??>
<configuration>
????
<system.serviceModel>
????????
<behaviors>
????????????
<serviceBehaviors>
????????????????
<behavior?name="Server.MyServiceBehavior">
??????????????????
<serviceMetadata?httpGetEnabled="true"?httpGetUrl="http://localhost:8080"?/>
??????????????????
<serviceDebug?includeExceptionDetailInFaults="true"?/>
??????????????????
<serviceCredentials>
????????????????????
<clientCertificate>
??????????????????????
<authentication?certificateValidationMode="Custom"?customCertificateValidatorType="Server.CustomX509CertificateValidator,Server"/>
????????????????????
</clientCertificate>
????????????????????
<serviceCertificate?findValue="MyServer"?storeLocation="CurrentUser"
??????????????????????x509FindType
="FindBySubjectName"?/>
??????????????????
</serviceCredentials>
????????????????
</behavior>
????????????
</serviceBehaviors>
????????
</behaviors>
??????
<bindings>
????????
<netTcpBinding>
??????????
<binding?name="NewBinding0">
????????????
<security?mode="Transport">
??????????????
<transport?clientCredentialType="Certificate"?/>
????????????
</security>
??????????
</binding>
????????
</netTcpBinding>
??????
</bindings>
????????
<services>
????????????
<service?behaviorConfiguration="Server.MyServiceBehavior"?name="Server.MyService">
????????????????
<endpoint?address="net.tcp://localhost:8081"?binding="netTcpBinding"?contract="Server.IMyService"?bindingConfiguration="NewBinding0"/>??????????????
????????????
</service>
????????
</services>
????
</system.serviceModel>
</configuration>

?

解釋一下:
<authentication certificateValidationMode="Custom" customCertificateValidatorType="Server.CustomX509CertificateValidator,Server"/></clientCertificate>
這一行的意思就是通知WCF服務(wù)端,驗證客戶端證書的模式為自定義,驗證時調(diào)用Server.CustomX509CertificateValidator這個類來完成驗證

<serviceCertificate findValue="MyServer" storeLocation="CurrentUser" x509FindType="FindBySubjectName" />
這一行的意思是WCF服務(wù)端驗證證書時,到CurrentUser這個位置查詢CN=MyServer的證書

最后在Program.cs里啟用WCF,內(nèi)容如下:

using?System;??
using?System.ServiceModel;

namespace?Server
{
????
class?Program
????{
????????
static?void?Main(string[]?args)
????????{
????????????ServiceHost?host?
=?new?ServiceHost(typeof(MyService));
????????????host.Open();
????????????Console.ReadKey();
????????}
????}
}

?

build一下,如果編譯無錯的話,服務(wù)端完工,可以運行一下,將彈出一個DOS命令窗口(不過什么輸出也沒有),只要不報錯,就表明Ok了,先不要急著關(guān),嘗試瀏覽一下:

http://localhost:8080/(這個地址哪里來的?回頭看下App.config,里面有一行<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8080/" />,呵呵,明白了吧) 正常的話,應(yīng)該類似下圖所示:

3.客戶端調(diào)用

下面生成服務(wù)端的代理和配置文件,客戶端開發(fā)將用到這二個文件,同樣先進(jìn)入vs2008的命令行狀態(tài),輸入:

svcutil.exe http://localhost:8080/ /d:c:"123"

注意:輸入這一行命令的時候,請確保服務(wù)端程序正在運行。這一句的意思就是在c:"123"目錄下輸出WCF的代理文件和配置文件

打開vs.net2008,再新建一個控制臺應(yīng)用程序,可以命名為Client

把c:"123"下生成的二個文件MyService.cs,output.config添加到Client項目中,同時將output.config改名為App.Config

Progam.cs代碼內(nèi)容如下:

using?System;?
namespace?Client
{
????
class?Program
????{
????????
static?void?Main(string[]?args)
????????{
????????????
using?(MyServiceClient?client?=?new?MyServiceClient())
????????????{
????????????????Console.WriteLine(
"客戶端輸出:");
????????????????Console.WriteLine(client.Test());
????????????}?
????????????Console.ReadKey();
????????}
????}
}

同時,參考下面的內(nèi)容手動修改一下App.Config文件

<?xml?version="1.0"?encoding="utf-8"?>
<configuration>
????
<system.serviceModel>
??????
<behaviors>
????????
<endpointBehaviors>
??????????
<behavior?name="NewBehavior">
????????????
<clientCredentials>
??????????????
<clientCertificate?findValue="MyClient"?x509FindType="FindBySubjectName"/>
??????????????
<serviceCertificate>
????????????????
<authentication?certificateValidationMode="None"?/>
??????????????
</serviceCertificate>
????????????
</clientCredentials>
??????????
</behavior>
????????
</endpointBehaviors>
??????
</behaviors>
??????
<bindings>
????????????
<netTcpBinding>
????????????????
<binding?name="NetTcpBinding_IMyService"?closeTimeout="00:01:00"
????????????????????openTimeout
="00:01:00"?receiveTimeout="00:10:00"?sendTimeout="00:01:00"
????????????????????transactionFlow
="false"?transferMode="Buffered"?transactionProtocol="OleTransactions"
????????????????????hostNameComparisonMode
="StrongWildcard"?listenBacklog="10"
????????????????????maxBufferPoolSize
="524288"?maxBufferSize="65536"?maxConnections="10"
????????????????????maxReceivedMessageSize
="65536">
????????????????????
<readerQuotas?maxDepth="32"?maxStringContentLength="8192"?maxArrayLength="16384"
????????????????????????maxBytesPerRead
="4096"?maxNameTableCharCount="16384"?/>
????????????????????
<reliableSession?ordered="true"?inactivityTimeout="00:10:00"
????????????????????????enabled
="false"?/>
????????????????????
<security?mode="Transport">
????????????????????????
<transport?clientCredentialType="Certificate"?protectionLevel="EncryptAndSign"?/>
????????????????????????
<message?clientCredentialType="Windows"?/>
????????????????????
</security>
????????????????
</binding>
????????????
</netTcpBinding>
????????
</bindings>
????????
<client>
????????????
<endpoint?address="net.tcp://localhost:8081/"?binding="netTcpBinding"
????????????????bindingConfiguration
="NetTcpBinding_IMyService"?contract="IMyService"
????????????????name
="NetTcpBinding_IMyService"?behaviorConfiguration="NewBehavior">
????????????????
<identity>
????????????????????
<dns?value="MyServer"?/>
????????????????
</identity>
????????????
</endpoint>
????????
</client>
????
</system.serviceModel>
</configuration>

?

主要是增加了一個節(jié)點
<behaviors>
??????? <endpointBehaviors>
????????? <behavior name="NewBehavior">
??????????? <clientCredentials>
????????????? <clientCertificate findValue="MyClient" x509FindType="FindBySubjectName"/>
????????????? <serviceCertificate>
??????????????? <authentication certificateValidationMode="None" />
????????????? </serviceCertificate>
??????????? </clientCredentials>
????????? </behavior>
??????? </endpointBehaviors>
????? </behaviors>

上面紅色的行,就是表明客戶端調(diào)用時,將用MyClient證書來驗證

?

同時<endpoint address="net.tcp://localhost:8081/" binding="netTcpBinding"
??????????????? bindingConfiguration="NetTcpBinding_IMyService" contract="IMyService"
??????????????? name="NetTcpBinding_IMyService" behaviorConfiguration="NewBehavior">這一句,增加了behaviorConfiguration="NewBehavior"

好了,Build一下,沒有問題的話,開發(fā)完成


4.測試:
先啟動服務(wù)端,再啟動客戶端,運行結(jié)果如下:

(轉(zhuǎn)貼請注明來自"菩提樹下的楊過") http://www.cnblogs.com/yjmyzz/archive/2008/08/20/1272550.html

?

注意服務(wù)端server.exe輸出的信息中3E4D4B64A90810B6CFF9B1DD2390D8C9488747BF與客戶端證書完全吻合

最后來談?wù)劮职l(fā)問題,上面這一系列測試都是在同一臺機(jī)器完成的,客戶端總不可能總是跟服務(wù)端在一臺機(jī)器上,這個好辦,在IE里把MyClient證書導(dǎo)出,注意導(dǎo)出時要選擇"是,導(dǎo)出私鑰",然后把導(dǎo)出的pfx文件連同客戶端程序一起分發(fā)到目標(biāo)客戶機(jī)即可,這里要注意幾點:

a.客戶端上的App.config里,要把<endpoint address="net.tcp://localhost:8081/" 中的localhost換成服務(wù)端的Ip地址
b.注意防火墻參數(shù)設(shè)置(本例中,即要把tcp:8081端口打開)

?

總結(jié)

以上是生活随笔為你收集整理的【转】x.509证书在WCF中的应用(CS篇)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。