1. 程式人生 > >微信退款IIS呼叫介面(https)提示錯誤的解決方案

微信退款IIS呼叫介面(https)提示錯誤的解決方案

Aps.net在IIS伺服器中使用windows的容器中的證書訪問https服務(在windows服務和COM+服務中有同樣的這個問題)

問題描述:

在使用aps.net開發web應用的時候,我們需要使用證書去訪問https的介面,我們在開發的時候可執行,但是部署到iis伺服器上之後,便發現所有使用證書訪問的地方都拋異常?返回的錯誤大致為:1、webrequest.GetResponse()函式拋異常;2、System.Net.WebException:請求被中止,未能建立 SSL/TLS安全通道;3、store.Certificates.Find 函式查找出來的證書個數為0;

問題分析:

開發環境中直接使用vs除錯工具可以正常執行,不是之後便執行不正常,在排查iis配置問題的情況下,基本上可以判斷是許可權問題,在開發工作下執行,使用的是當前使用者的許可權,安裝在本機的證書基本也是該使用者下安裝的,許可權肯定沒問題,但是在iis伺服器下面,則不是以當前使用者的環境執行,當然沒許可權讀取證書。

Windows中證書存放分析:

Windows存放證書有2種,一種本地計算機證書存取路徑,另一是本地使用者賬戶證書存取路徑,存放的路徑分別為:LOCAL_MACHINE\MY 和  CURRENT_USER\My(My為windows下預設路徑)

1、本地使用者賬戶證書存取路徑表示一般使用者安裝的證書存放地,使用者開啟的程序時,載入證書都從這裡個路徑進行載入;但是服務程序則不能從該路徑載入證書。

2、本地計算機證書存取路徑表示服務型別的程序使用證書的時候,預設從該路徑載入,使用者安裝的證書並不會同步到該路徑。

IIS一般都是以系統內建的一些賬戶啟動,這些賬戶是沒有許可權訪問CURRENT_USER目錄下的證書的,所以我們需要將證書安裝到LOCAL_MACHINE下去。

操作方法:

1、開啟mmc(在搜尋程式中輸入mmc,然後回車)進入如下介面:

2、選擇“檔案 》 新增/刪除管理單元”進入如下介面

3、左邊選擇證書,點選“新增”,出現如下介面

4、選擇計算機賬戶,點選下一步

5、這裡選擇“本地計算機”(預設選擇),點選完成後,再點“確定”,介面成下面樣

6、右“鍵個人 》 證書”,出現匯入證書介面

8、安裝步驟匯入pfx或者.p12格式的證書,導完之後右邊出現剛剛匯入的證書

到這裡證書匯入算是完成了。

證書導完之後,試下自己的網站是否能夠發起https請求,如果能夠,則到此為止,如果不能,還需要將證書許可權給指定的系統使用者。方法如下:

2、在64位系統下,安裝之後工具在C:\Program Files (x86)\Windows ResourceKits\Tools路徑下,使用CD \D指令定位到該目錄下

3、使用剛剛安裝的工具,給指定使用者開證書的訪問許可權,使用指令如下:

winhttpcertcfg.exe -g -c LOCAL_MACHINE\MY -s"jackliu_test_company" -a "NETWORKSERVICE"

這裡引數可以使用--help具體檢視,我只描述幾個最簡單的

-g 表示給該使用者增加證書的訪問許可權,如果將該引數變成-r表示移除使用者的證書訪問許可權

-c 後面引數表示證書的路徑,LOCAL_MACHINE可以替換為CURRENT_USER,但是必須如果使用CURRENT_USER下的證書,即使給了許可權還是不能正常執行。

-s 後面引數表示證書的名稱。注意:證書名稱不是證書的檔名稱,名稱可以從mmc管理工具中證書列表的“頒發給”欄位。

-a 後面引數表示使用者名稱稱,一般IIS執行使用者為:NETWORKSERVICE或者 ASPNET使用者,這裡如果開了這兩個使用者還是不行的話,則需要給windows認證的一個使用者也開下證書訪問許可權。authenticatedUsers

指令如下:(此處是關鍵)

winhttpcertcfg.exe -g -c LOCAL_MACHINE\MY -s"你的證書名稱"-a "NETWORKSERVICE"

winhttpcertcfg.exe -g -c LOCAL_MACHINE\MY -s"你的證書名稱"-a "ASPNET"

winhttpcertcfg.exe -g -c LOCAL_MACHINE\MY -s"你的證書名稱"-a "Authenticated Users"

成功則出現如下字樣:

如果出現如下錯誤資訊:

則表示未找到證書,請安裝我上面講的如何安裝證書到LOCAL_NARCHANT下的說明。

如果出現如下錯誤資訊:

表示證書已經找到,但是沒找到使用者資訊

C#程式碼使用方法(直接使用windows下已經安裝的證書):

HttpWebResponse webreponse;

try

{

//系統必須已經匯入cert指向的證書

X509Store store = newX509Store("My", StoreLocation.LocalMachine);

store.Open(OpenFlags.ReadOnly |OpenFlags.OpenExistingOnly);

System.Security.Cryptography.X509Certificates.X509Certificate2cert =

 store.Certificates.Find(X509FindType.FindBySubjectName, "你的證書名稱", false)[0];

HttpWebRequest webrequest =(HttpWebRequest)HttpWebRequest.Create(url);

webrequest.ClientCertificates.Add(cert);

webrequest.Method = "post";

webrequest.KeepAlive = true;

webreponse = (HttpWebResponse)webrequest.GetResponse();

Stream stream =webreponse.GetResponseStream();

string resp = string.Empty;

using (StreamReader reader = newStreamReader(stream))

{

resp = reader.ReadToEnd();

}

strHtml = resp;

}

catch (Exception exp)

{

strHtml = exp.ToString();

}

幾個關鍵點:

1、X509Storestore = new X509Store("My", StoreLocation.LocalMachine);

這裡,My為證書安裝的模組邏輯,windows7下預設為My,StoreLocation.LocalMachine使用這個型別。

2、System.Security.Cryptography.X509Certificates.X509Certificate2cert =

store.Certificates.Find(X509FindType.FindBySubjectName,"你的證書名稱",false)[0];

這裡通過證書名稱查詢證書,證書名稱為證書列表中“頒發給欄位”。這裡返回是一個數組,如果你安裝多個相同名稱的證書,這裡可能會返回多個,這種情況需要根據證書具體定位是那個。