最近有個項目要調用客戶用java寫的帶https的webservice,對方提供了證書文件 test.pfx,我這裏調用方式以下:java
//webservice代理類 SvcService svc = new SvcService(); //證書文件路徑 string filePath = ConfigurationManager.AppSettings["pfxUrl"]; X509Certificate cert = new System.Security.Cryptography.X509Certificates.X509Certificate(filePath, "123456"); //將證書添加客戶端證書集合 svc.ClientCertificates.Add(cert); //webservice調用代碼...
測試調用報錯:請求被停止: 未能建立 SSL/TLS 安全通道,因而趕忙google,找到以下解決方案:web
在webservice代理類的構造函數中添加下面的代碼,繞過服務器證書驗證。安全
public static bool CheckValidationResult(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { return true; } public SvcService() { ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); this.Url = ConfigurationManager.AppSettings["host"]; }
本地vs環境下再試,好了!調用成功!不報錯了!因而趕忙發佈到IIS服務器上試一下,鬱悶的是服務器上竟然報錯,仍是這個未能建立 SSL/TLS 安全通道!服務器
因而繼續google,找到下面的解決方法:函數
1.將客戶端證書文件導入到本地計算機帳戶下的我的存儲區。工具
2.下載winhttpcertcfg.exe 這個工具,下載地址:http://www.microsoft.com/en-us/download/details.aspx?id=19801測試
3.安裝後通常是在C:\Program Files\Windows Resource Kits\Tools這個路徑下面。 進入cmd 執行以下命令:winhttpcertcfg -g -c LOCAL_MACHINE\MY -s "test" -a "NetworkService"網站
這裏解釋一下這幾個參數的含義:this
-g 是grant受權的意思,將該證書的使用權限授予某個用戶google
-c 是certstore證書存儲區,指定 本地計算機/當前用戶下的證書存儲區位置,咱們這裏是MY,我的存儲區
-s 是subjectstr 用於模糊匹配證書的一個字符串,咱們這裏用證書文件名 test
-a 是account要受權的用戶賬號
這裏要注意的是受權帳戶,IIS6下面通常用的是NetworkService,若是你用的IIS7,必需要保證你網站所用的應用程序池的 "標識"和要受權的帳戶一致。
執行成功以後,會列出模糊匹配出的證書列表和已經受權的帳戶。
而後程序代碼作以下更改:
//webservice客戶端代理類 SvcService svc = new SvcService(); //打開本地計算機下的我的證書存儲區 X509Store certStore = new System.Security.Cryptography.X509Certificates.X509Store(StoreName.My, StoreLocation.LocalMachine); certStore.Open(OpenFlags.ReadOnly); //根據名稱查找匹配的證書集合,這裏注意最後一個參數,傳true的話會找不到 X509Certificate2Collection certCollection = certStore.Certificates.Find(System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName, "test", false); //將證書添加至客戶端證書集合 svc.ClientCertificates.Add(certCollection[0]); //webservice調用代碼
再測試了一下,調用正常!至此這個問題算圓滿解決了!總結:咱們導入的客戶端證書並非全部的帳戶都能訪問和使用,由於咱們的開發服務器也就是VS自帶的服務器默認使用當前用戶,而當前用戶具備使用證書的權限,因此咱們在本地調試的時候,一切正常。當咱們將網站部署到IIS後,因爲IIS的使用的是內置帳戶不具備證書的使用權限,因此就出現了上述問題,這個時候咱們只需用winhttpcertcfg這個工具給指定帳戶授予使用證書的權限,就能夠正常調用啦!