正如我在以前的幾篇文章中所描述的那樣,自我託管SignalR很是容易設置。這很容易作到,若是您須要將SignalR做爲事件源鏈接到標準的基於Windows的應用程序(如服務,甚至是須要向許多用戶發送推送通知的WPF或Winforms桌面應用程序),這很好html

自託管的一個方面雖然不是那麼透明或有記錄,可是在SSL下運行自託管的SignalR服務。Windows證書存儲以及證書的建立,配置和安裝仍然很痛苦,由於Windows中沒有提供連接端點到證書的UI,而且該流程的端到端記錄不完整。一旦你知道須要調用什麼命令行工具就很容易,可是這個過程固然能夠更順暢,更好地記錄。所以,我在這裏從新討論這個主題,以提供更多詳細信息,並但願可以更加一致地描述爲自我託管OWIN服務(特別是SignalR)設置證書。java

自託管和OWIN

當您本身託管SignalR時,您實際上使用的是OWIN / Katana提供的託管服務。OWIN是一個低級規範,用於實現可互換使用的自定義託管提供程序。咱們的想法是將託管進程與特定實現分離並使其可插拔,所以您能夠選擇託管實現。ios

Katana是Microsoft的OWIN實現,它提供了幾個特定的​​實現。對於自託管,基於HttpListener的主機與IIS及其基礎架構徹底分離。對於在ASP.NET內部託管,還有一個基於ASP.NET的實現,用於在ASP.NET內部運行的SignalR應用程序。這兩種實現都爲SignalR提供了基本託管支持,所以大多數狀況下,相同的代碼庫可用於在ASP.NET下運行SignalR,或者在您本身的自託管EXE(如服務,控制檯或桌面應用程序)下運行。web

將證書綁定到SSL端口以進行自託管

HttpListener下的自託管很是精彩且徹底獨立,但不屬於IIS的一個缺點是它也不知道爲IIS安裝的證書,這意味着您要使用的證書必須是顯式綁定到端口。請注意,您可使用IIS證書,若是須要獲取完整證書以用於自託管應用程序,則經過IIS證書過程是獲取證書的最簡單方法。若是你須要一個本地測試證書,IIS的自簽名證書建立工具也很容易(我將在下面描述)。shell

如今讓咱們假設您已經在Windows證書庫中安裝了證書。爲了將證書綁定到自託管端點,您必須使用netsh命令行實用程序在計算機上註冊它(所有在一行上):瀏覽器

netsh http add sslcert ipport=0.0.0.0:8082 appid={12345678-db90-4b66-8b01-88f7af2e36bf} certhash=d37b844594e5c23702ef4e6bd17719a079b9bdf 

對於每一個端點映射,您須要提供3個值:安全

  • 標識ip和端口的
    ipport指定爲ipport = 0.0.0.0:8082,其中零表示端口8082上的全部IP地址。不然,您還能夠指定特定的IP地址。服務器

  • certhash是證書的指紋
    certhash是將證書映射到上面的IP端點的id。您能夠經過查看Windows證書存儲區中的證書來查找此哈希。更多關於這一點。架構

  • 爲HttpListener Hosting修復的AppID
    此值是靜態魔術值,所以始終使用appid={12345678-db90-4b66-8b01-88f7af2e36bf}一旦運行了上述命令,您應該經過查看綁定來檢查它是否有效。用這個:

netsh http show sslcert ipport=0.0.0.0:8082 

這給你一個這樣的顯示:

netsh的

查找CertHash

我在上面提到了certhash:要找到certhash,你須要找到證書的ThumbPrint,它能夠經過如下幾種方式找到:

  • IIS證書管理器
  • Windows證書存儲管理器

使用IIS獲取證書信息

若是安裝了IIS,前者是最簡單的。在這裏,您能夠輕鬆查看全部已安裝的證書,此UI也是建立本地自簽名證書的最簡單方法。

要查找現有證書,只需打開IIS管理控制檯,轉到計算機節點,而後轉到服務器證書:

IISCerts

您能夠在最右側的列中看到證書哈希。您也能夠雙擊並打開證書,而後進入證書的詳細信息。查找包含哈希的指紋。

CertificateDetails 

遺憾的是,這些位置都不容易複製哈希,所以您必須手動複製它或從對話框中的指紋數據中刪除空格。

使用IIS建立自簽名證書

若是您尚未完整的服務器證書,可是您但願在本地使用SSL操做進行測試,則還可使用IIS Admin界面輕鬆建立自簽名證書。IIS管理控制檯提供了建立本地自簽名證書的最簡單方法之一。

這是怎麼作的:

  • 轉到IIS服務管理器的計算機根目錄
  • 轉到IIS部分中的服務器證書項
  • 在左側單擊「建立自簽名證書」
  • 爲其命名,而後選擇我的存儲
  • 單擊肯定

IisCreateCert

這就是建立自簽名本地證書的所有內容。

將自簽名證書複製到受信任的根證書存儲區

擁有自簽名證書後,還須要一個步驟才能使證書受信任,所以Http客戶端將在您的計算機上接受它而不會出現證書錯誤。該過程涉及將證書從我的存儲複製到受信任的機器商店。

去作這個:

  • 從StartMenu使用「 管理計算機證書」
  • 進入我的| 證書並找到您的證書
  • 將證書拖放並複製(Ctrl-拖動)爲「受信任的根證書」 證書

TrustCertificate

您如今應該擁有瀏覽器可信賴的證書。這適用於IE,Chrome和Safari,但FireFox須要一些特殊步驟(感謝Eric Lawrence),Opera還須要特定的證書註冊。

使用完整的IIS證書

自簽名證書很是適合在SSL下進行測試以確保您的應用程序正常工做,但對於生產應用程序而言並非很好,由於證書必須安裝在您但願信任此證書的任何計算機上,這是一件麻煩事。

一旦你去生產,特別是公共生產,你須要一個由$$$的全球證書頒發機構簽署的「官方」證書(或者如今是LetsEncrypt)。

最簡單的方法是購買或生成完整的IIS證書並將其安裝在IIS中。IIS證書也能夠用於使用HttpListener的自託管應用程序,所以它能夠與自託管SignalR或任何HttpListener應用程序一塊兒使用。

所以,一旦時間到了,請經過IIS註冊新證書,而後使用netsh http add sslcert如上所示註冊該證書。在大多數狀況下,公共SSL證書已經被識別,所以不須要進一步移動證書存儲 - 您只須要將netsh註冊綁定到特定端口和應用程序ID。

使用SSL運行SignalR

安裝證書後,將SignalR切換爲SSL啓動就像更改啓動URL同樣簡單。

自託管服務器配置

在自託管服務器中,您如今能夠在啓動工廠調用中指定新的SSL URL:

var signalR = WebApp.Start<SignalRStartup>([https://*:8082/](https://*:8082/)); 

這會將SignalR綁定到端口8082上的全部IP地址。您還能夠指定特定的IP地址,但使用*更具可移植性,尤爲是將值設置爲共享配置文件的一部分時。

若是你回憶起我上次的自託管帖子,OWIN使用一個啓動類(在這種狀況下是SignalRStartup)來處理OWIN和SignalR HubConfiguration,但惟一須要改變的是啓動URL,你的自託管服務器已準備就緒走。

SignalR Web App頁面URL配置

在Web頁面上使用SignalR服務到集線器或鏈接更改腳本URL,爲您的集線器或鏈接加載SignalR客戶端庫,以下所示:

<script src="[https://RasXps:8082/signalr/hubs">script> 

這裏的RasXps是我註冊證書的確切本地機器名。與全部證書同樣,請確保域名與證書的名稱徹底匹配。對於本地計算機,若是證書已默認分配給本地計算機NetBios名稱,則表示不使用localhost不要使用您的IP地址 - 使用分配證書的任何內容。

您還須要將集線器Url分配給您的SSL URL,做爲調用$ connection.hub.start的SignalR啓動例程的一部分:

$.connection.hub.url = self.hubUrl; // ie. "[https://rasxps:8082/signalR](https://rasxps:8082/signalR);" 

有關更多上下文,這是我用來啓動集線器的典型集線器啓動/錯誤處理程序設置例程:

startHub: function () { $.connection.hub.url = self.hubUrl; // ie. "https://rasxps:8082/signalR"; // capture the hub for easier access var hub = $.connection.queueMonitorServiceHub; // This means the <script> proxy failed - have to reload if (hub == null) { self.viewModel.connectionStatus("Offline"); toastr.error("Couldn't connect to server. Please refresh the page."); return; } // Connection Events hub.connection.error(function (error) { if (error) toastr.error("An error occurred: " + error.message); self.hub = null; }); hub.connection.disconnected(function (error) { self.viewModel.connectionStatus("Connection lost"); toastr.error("Connection lost. " + error); // IMPORTANT: continuously try re-starting connection setTimeout(function () { $.connection.hub.start(); }, 2000); }); // map client callbacks hub.client.writeMessage = self.writeMessage; hub.client.writeQueueMessage = self.writeQueueMessage; hub.client.statusMessage = self.statusMessage; … // start the hub and handle after start actions $.connection.hub .start() .done(function () { hub.connection.stateChanged(function (change) { if (change.newState === $.signalR.connectionState.reconnecting) self.viewModel.connectionStatus("Connection lost"); else if (change.newState === $.signalR.connectionState.connected) { self.viewModel.connectionStatus("Online"); // IMPORTANT: On reconnection you have to reset the hub self.hub = $.connection.queueMonitorServiceHub; } else if (change.newState === $.signalR.connectionState.disconnected) self.viewModel.connectionStatus("Disconnected"); }) .error(function (error) { if (!error) error = "Disconnected"; toastr.error(error.message); }) .disconnected(function (msg) { toastr.warning("Disconnected: " + msg); }); self.viewModel.connectionStatus("Online"); // get initial status from the server (RPC style method) self.getServiceStatus(); self.getInitialMessages(); }); }, 

從代碼角度來看,除了兩個小的URL代碼更改以外,SSL操做沒有任何變化,這很好。

並且......你已經完成了!

SSL配置

隨着愈來愈多的應用程序須要傳輸安全性,SSL使用變得愈來愈重要。即便您的自託管SignalR應用程序沒有明確要求SSL,若是SignalR客戶端託管在運行SSL的網頁內,您必須在SSL下運行SignalR,若是您但願它在沒有瀏覽器錯誤消息或故障的狀況下運行一些瀏覽器會拒絕SSL頁面上的混合內容。

SSL配置老是拖累,由於它不直觀,須要一些研究。若是HttpListener證書配置就像今天或更好的IIS配置同樣簡單,若是自託管應用程序可使用已安裝的IIS證書,那就太好了。不幸的是,它並不那麼容易,你須要運行一個命令行實用程序,其中包含一些魔術ID。

安裝證書並非火箭科學,但它並無徹底記錄在案。在尋找信息的過程當中,我發現了一些不相關的文章,討論了這個過程,但有些文章已通過時,其餘文章沒有具體涉及SignalR甚至是自託管網站。因此我但願這篇文章可以在適當的環境中更容易地找到這些信息。

本文重點介紹使用SSL的SignalR自託管,但相同的概念能夠應用於使用HttpListener的任何自託管應用程序。

資源