標籤:
本文章其實最主要資訊是:
問題出在那個小小的*號上——IIS6中不支援萬用字元,第一部分為空白時表示(All Unsigned),而IIS7中同時支援空或萬用字元的寫法,如果為空白則自動轉為*:443:,我們將調用行改為:AddHttpsBinding(":443:", "MY", hash);後,問題解決。
文章轉自:http://linwx1978.blog.163.com/blog/static/1504106920111281434624/
最近剛剛解決了一個困擾了很久的問題,發出來大家共用一下。
問題很簡單,就是我們在做一個自動部署網站的程式,需要同時支援在IIS6與IIS7實現HTTPS,也就是要編程實現增加HTTPS綁定,開始的時候My Code是這樣的:
private void WriteBinaryArrayToDirectoryEntry(PropertyValueCollection entry, byte[] data)
{
string[] arrStr = new string[data.Length];
for (int i = 0; i < data.Length; i++)
{
arrStr[i] = String.Format("{0:x2}", data[i]);
}
object[] arrObj = new object[arrStr.Length];
arrStr.CopyTo(arrObj, 0);
entry.Clear();
entry.Add(arrObj);
}
public void AddHttpsBinding(string binding, string nameStore, byte[] hash)
{
DirectoryEntry entry = new DirectoryEntry("IIS://localhost/W3SVC/1");//指向Default Web Site
entry.Properties[”SecureBindings"].Clear();
entry.Properties["SecureBindings"].Add(binding);
WriteBinaryArrayToDirectoryEntry(entry.Properties["SSLCertHash"], hash);
entry.CommitChanges();
}
其中標出來的那一行需要注意,如果需要指向非預設的網站就可能需要修改,當然,這是題外話。
調用如下:
AddHttpsBinding("*:443:", "MY", hash);
*:443:的意思是指定443連接埠,任意IP(All Unassigned IP)。
結果,在IIS7上運行良好,在IIS6及IIS5上就遇到了很多問題,HTTPS無法訪問。
首先我們檢查了HTTPS綁定,結果發現認證綁定失敗。用Metabase Explorer檢查/LM/W3SVC/1下應該有三項與HTTPS綁定有關的條目,分別是:
SecureBindings,指定連接埠、IP及HEADER資訊。
SSLCertHash,指定目標認證的雜湊值。
SSLStoreName,指定目標認證所在的目錄。
綁定成功的情況下,這三個條目都應該出現,並且填入我們指定的值,但上述程式在IIS6上運行之後,只有前兩個條目而沒有SSLStoreName,導致HTTPS服務無法找到目標認證。
原因是,在IIS6中,必需設定SSLStoreName,而且還必需在設定SSLCertHash之前。但在IIS7中,SSLStoreName由系統自動設定,如果程式試圖自行設定,系統會拋出異常:“A specified logon session does not exist. It may already have been terminated. (Exception from HRESULT: 0x80070520)”。
結果,我們只好把程式改成這樣:
public void AddHttpsBinding(string binding, string nameStore, byte[] hash)
{
DirectoryEntry entry = new DirectoryEntry("IIS://localhost/W3SVC/1");
entry.Properties[”SecureBindings"].Clear();
entry.Properties[”SecureBindings"]Add(binding);
WriteBinaryArrayToDirectoryEntry(entry.Properties["SSLCertHash"], hash);
entry.CommitChanges();
if (TryGetValue("IIS://localhost/W3SVC/1", "SSLStoreName") == "")
{
entry.Properties["SSLStoreName"].Clear();
entry.Properties["SSLStoreName"].Add(nameStore);
WriteBinaryArrayToDirectoryEntry(entry.Properties["SSLCertHash"], hash);
entry.CommitChanges();
}
}
加上了藍色的部分,在前面的設定結束之後,測試SSLStoreName是否為空白,如果為空白,則依次設定SSLStoreName和SSLCertHash。在IIS6和IIS7上測試均成功。
然後我們就遇到了第二個問題:現在IIS6上綁定是成功的,從IIS管理器上也可以看到綁定的認證資訊了,但仍然無法用HTTPS訪問,下載了一個微軟的SSL工具SSL Diagnostics測試了一下,說綁定的IP與SSL的IP不符,可能有問題。於是我們開啟IIS管理器,在網站上點擊右鍵,到屬性->Web Site頁,點擊Advanced,在Multiple SSL identities for this Web Site一欄中,發現IP Address一欄寫的居然是255.255.255.255,果然有問題!手動將其改為(All Unsigned)之後,問題解決。
使用Metabase Explorer檢查,發現SecureBindings中寫的是:443:,也就是說,問題出在那個小小的*號上——IIS6中不支援萬用字元,第一部分為空白時表示(All Unsigned),而IIS7中同時支援空或萬用字元的寫法,如果為空白則自動轉為*:443:,我們將調用行改為:
AddHttpsBinding(":443:", "MY", hash);
後,問題解決。
IIS6與IIS7在編程實現HTTPS綁定時的細微差別