https://weblog.west-wind.com/posts/2013/Sep/23/Hosting-SignalR-under-SSLhttps

 2013年9月23日•来自毛伊岛,HI•    24条评论
 

正如我在之前的几篇文章中所描述的那样,自我托管SignalR非常容易设置。这很容易做到,如果您需要将SignalR作为事件源连接到标准的基于Windows的应用程序(如服务,甚至是需要向许多用户发送推送通知的WPF或Winforms桌面应用程序),这很好。

自托管的一个方面虽然不是那么透明或有记录,但是在SSL下运行自托管的SignalR服务。Windows证书存储以及证书的创建,配置和安装仍然很痛苦,因为Windows中没有提供链接端点到证书的UI,并且该流程的端到端记录不完整。一旦你知道需要调用什么命令行工具就很容易,但是这个过程当然可以更顺畅,更好地记录。因此,我在这里重新讨论这个主题,以提供更多详细信息,并希望能够更加一致地描述为自我托管OWIN服务(特别是SignalR)设置证书。

自托管和OWIN

当您自己托管SignalR时,您实际上使用的是OWIN / Katana提供的托管服务。OWIN是一个低级规范,用于实现可互换使用的自定义托管提供程序。我们的想法是将托管进程与特定实现分离并使其可插拔,因此您可以选择托管实现。

Katana是Microsoft的OWIN实现,它提供了几个特定的​​实现。对于自托管,基于HttpListener的主机与IIS及其基础架构完全分离。对于在ASP.NET内部托管,还有一个基于ASP.NET的实现,用于在ASP.NET内部运行的SignalR应用程序。这两种实现都为SignalR提供了基本托管支持,因此大多数情况下,相同的代码库可用于在ASP.NET下运行SignalR,或者在您自己的自托管EXE(如服务,控制台或桌面应用程序)下运行。

将证书绑定到SSL端口以进行自托管

HttpListener下的自托管非常精彩且完全独立,但不属于IIS的一个缺点是它也不知道为IIS安装的证书,这意味着您要使用的证书必须是显式绑定到端口。请注意,您可以使用IIS证书,如果需要获取完整证书以用于自托管应用程序,则通过IIS证书过程是获取证书的最简单方法。如果你需要一个本地测试证书,IIS的自签名证书创建工具也很容易(我将在下面描述)。

现在让我们假设您已经在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

这给你一个这样的显示:

查找CertHash

我在上面提到了certhash:要找到certhash,你需要找到证书的ThumbPrint,它可以通过以下几种方式找到:

  • IIS证书管理器
  • Windows证书存储管理器

使用IIS获取证书信息

如果安装了IIS,前者是最简单的。在这里,您可以轻松查看所有已安装的证书,此UI也是创建本地自签名证书的最简单方法。

要查找现有证书,只需打开IIS管理控制台,转到计算机节点,然后转到服务器证书:

您可以在最右侧的列中看到证书哈希。您也可以双击并打开证书,然后进入证书的详细信息。查找包含哈希的指纹。

遗憾的是,这些位置都不容易复制哈希,因此您必须手动复制它或从对话框中的指纹数据中删除空格。

使用IIS创建自签名证书

如果您还没有完整的服务器证书,但是您希望在本地使用SSL操作进行测试,则还可以使用IIS Admin界面轻松创建自签名证书。IIS管理控制台提供了创建本地自签名证书的最简单方法之一。

这是怎么做的:

  • 转到IIS服务管理器的计算机根目录
  • 转到IIS部分中的服务器证书项
  • 在左侧单击“创建自签名证书”
  • 为其命名,然后选择个人存储
  • 单击确定

这就是创建自签名本地证书的全部内容。

将自签名证书复制到受信任的根证书存储区

拥有自签名证书后,还需要一个步骤才能使证书受信任,因此Http客户端将在您的计算机上接受它而不会出现证书错误。该过程涉及将证书从个人存储复制到受信任的机器商店。

去做这个:

  • 从StartMenu使用“ 管理计算机证书”
  • 进入个人| 证书并找到您的证书
  • 将证书拖放并复制(Ctrl-拖动)为“受信任的根证书” 证书

您现在应该拥有浏览器可信赖的证书。这适用于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的任何自托管应用程序。

资源

 
 

在SSL / https下托管SignalR的更多相关文章

  1. 用SignalR 2.0开发客服系统[系列4:负载均衡的情况下使用SignalR]

    前言 交流群:195866844 目录: 用SignalR 2.0开发客服系统[系列1:实现群发通讯] 用SignalR 2.0开发客服系统[系列2:实现聊天室] 用SignalR 2.0开发客服系统 ...

  2. Java调用使用SSL/HTTPS协议来传输的axis webservice服务

    使用SSL/HTTPS协议来传输 Web服务也可以使用SSL作为传输协议.虽然JAX-RPC并没有强制规定是否使用SSL协议,但在tomcat 下使用HTTPS协议. 1.使用JDK自带的工具创建密匙 ...

  3. apache Tomcat配置SSL(https)步骤

    Tomcat配置https 1      生成Server端安全证书 要实现通信加密,首先要在本地准备一份符合X.509标准的Server端安全证书.如果有条件的话,可以向权威CA申请一份经过认证的安 ...

  4. java ssl https 连接详解 生成证书 tomcat keystone

    java ssl https 连接详解 生成证书 我们先来了解一下什么理HTTPS 1. HTTPS概念 1)简介 HTTPS(全称:Hypertext Transfer Protocol over ...

  5. Charles的HTTPS抓包方法及原理,下载安装ssl/https证书

    转自:https://zhubangbang.com/charles-https-packet-capture-method-and-principle.html 本文的Charles,适应windo ...

  6. Nginx知多少系列之(五)Linux下托管.NET Core项目

    目录 1.前言 2.安装 3.配置文件详解 4.Linux下托管.NET Core项目 5.Linux下.NET Core项目负载均衡 6.Linux下.NET Core项目Nginx+Keepali ...

  7. nginx普通配置/负载均衡配置/ssl/https配置

    1.nginx普通配置 server { listen ; server_name jqlin.lynch.com; access_log /var/log/nginx/main.log main; ...

  8. Ettercap结合sslstrip对ssl/https进行攻击

    Ettercap是一个非常强大的嗅探欺骗工具:在以往的ettercap的使用过程中,我们大多用来嗅探http,ftp,和一些加密比较简单的邮箱等的密码,对于新型的ssl/https等的加密协议就显得不 ...

  9. SSL HTTPS 生成证书

    SSL HTTPS 一.生成服务器私钥.公钥 $ openssl genrsa -out server.key 2048 $ openssl rsa -in server.key -pubout -o ...

随机推荐

  1. 怎么解决docker pull拉取镜像速度过慢的问题

    在我们安装了docker之后,在利用docker pull下载镜像的时候,由于国内的源会出现的问题就是速度真的很慢,可以用龟速来形容,最痛苦的是当你耐心的等待几个小时之后,出现unexpected E ...

  2. 3194. 【HNOI模拟题】化学(无标号无根树计数)

    Problem 求\(n\)个点的每个点度数不超过\(4\)的无标号无根树个数. Data constraint \(1\le n\le 500\) Solution 尝试着把问题一般化.我们来考虑一 ...

  3. SpringBoot入门:Hello World

    1.Open IDEA,choose "New-->Project" 2.Choose "Spring Initializr" 3. Choose jav ...

  4. head里两个重要标签base和meta

    base标签 <base href="../"> 我们并不常用的一个标签,但是一旦用得不当会带来灾难性的影响. 它会影响到所有页面上的href和src属性相对路劲的定位 ...

  5. Telegraf+InfluxDB+Grafana搭建服务器监控平台

    Telegraf+InfluxDB+Grafana搭建服务器监控平台 tags:网站 个人网站:https://wanghualong.cn/ 效果展示 本站服务器状态监控:https://statu ...

  6. 提取 linux 文件目录结构

    提取 linux  文件的目录结构 find /home/user1/ -type d |while read line ;do mkdir -p /home/user2/$line;done

  7. package.json 里的 dependencies和devDependencies区别

    dependencies(依赖的意思): 通过 --save 安装,是需要发布到生产环境的.比如项目中使用react,那么没有这个包的依赖就会报错,因此把依赖写入dependencies devDep ...

  8. HTTP协议 详解

    前言 掌握HTTP协议是每一个开发者的基础,超详细的HTTP协议笔记 正文 HTTP协议格式总览 HTTP line HTTP Method(方法) 介绍了我们请求希望执行的操作类型. 方法有: GE ...

  9. HttpUtility.UrlEncode()关于空格的编码问题

    因为 HttpUtility.UrlEncode 在 Encode 的时候, 将空格转换成加号"+", 在 Decode 的时候将"+"号转为空格, 但是浏览器 ...

  10. java程序设计习题总结

    ---恢复内容开始--- main()方法的参数名可以改变:main()方法的参数个数不可以改变. 当一个程序没有main()方法是,是可以编译通过的,但是不能给运行,因为找不到一个主函数入口. 标识 ...