具有自签名 SSL 和自托管的 SignalR [英] SignalR with Self-Signed SSL and Self-Host

查看:30
本文介绍了具有自签名 SSL 和自托管的 SignalR的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在研究中碰碰运气,但到目前为止没有任何乐趣.

Tried my luck at research, but so far no joy.

我想将 SignalR javascript 客户端连接到绑定到自签名 SSL 证书的自托管 SignalR Windows 服务.

I would like to connect a SignalR javascript client to a self-hosted SignalR Windows Service binding to a self-signed SSL certificate.

我的应用程序在 http 上运行良好,但是当 Owin WebApplication 开始使用 https 时,客户端反复断开连接.

My application works quite well over http, but the client repetitively disconnects when the Owin WebApplication starts using https.

这是我为使用 SSL 配置 SignalR 所做的工作.

Here is what I've done to configure SignalR with SSL.

  1. 使用 IIS 创建自签名证书
  2. 将证书导入 mmc 中的受信任根证书颁发机构(不确定是否有帮助)
  3. 运行 NETSH 命令将 SSL 绑定到端口 8080

  1. Created a Self-Signed certificate using IIS
  2. Imported the certificate into the Trusted Root Certification Authorities in the mmc (not sure if that helped)
  3. Ran NETSH command to bind SSL to port 8080

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

  • 在自托管的 HubConnection 实例中添加代码以添加这样的导出 SSL(尽管这应该无关紧要,因为客户端无法连接):

  • Added code in self-hosted HubConnection instances to add exported SSL like this (though this shouldn't matter because it's the client that cannot connect):

    if (File.Exists("MyCert.cer") 
        && Settings.GetSetting(Settings.Setting.SrProtocol).Equals("https", StringComparison.InvariantCultureIgnoreCase))
            connection.AddClientCertificate(X509Certificate.CreateFromCertFile("MyCert.cer"));
    

  • 使用 https 启动 Owin WebApplication(这应该在 http.sys 中创建绑定)

  • Starting Owin WebApplication using https (this should create the binding in http.sys)

    string registerUrl = string.Format("{0}://SOME.WHERE.COM:{1}", Service.Server.SrProtocol, Service.Server.SrPort);
    WebApp.Start<StartUp>(registerUrl);
    

  • 在 SignalR 2.0 文档中,它说:

    In the SignalR 2.0 documentation, it says:

    要启动 Web 服务器,请调用 WebApplication.Start(endpoint).您现在应该可以在浏览器中导航到端点/信号/集线器.

    To start the web server, call WebApplication.Start(endpoint). You should now be able to navigate to endpoint/signalr/hubs in your browser.

    当我浏览到 URL http://SOME.WHERE.COM:8080/signalr/hubs我成功接收到驱动 SignalR 的 javascript.

    When I browse to the URL http://SOME.WHERE.COM:8080/signalr/hubs I am successful receiving the javascript that drives SignalR.

    当我浏览到 URL https://SOME.WHERE.COM:8080/signalr/hubs我没有成功,并且使用 FF 收到与服务器的连接已重置".

    When I browse to the URL https://SOME.WHERE.COM:8080/signalr/hubs I am unsuccessful and I receive "The connection to the server was reset" using FF.

    我考虑过的一些额外要点:

    Some additional points I've considered:

    • NETSH SHOW 表示网址已注册

    • NETSH SHOW indicates the url is registered

    URL group ID: E300000240000022
    State: Active
    Request queue name: Request queue is unnamed.
    Properties:
        Max bandwidth: inherited
        Max connections: inherited
        Timeouts:
            Timeout values inherited
        Number of registered URLs: 1
        Registered URLs: HTTPS://SOME.WHERE.COM:8080/
    

  • NETSH SHOW 表示 SSL 证书绑定到 8080:

  • NETSH SHOW indicates the SSL certificate is bound to 8080:

    IP:port                 : 0.0.0.0:8080 
    Certificate Hash        : 123456f6790a35f4b017b55d09e28f7ebe001bd
    Application ID          : {12345678-db90-4b66-8b01-88f7af2e36bf} 
    Certificate Store Name  : (null) 
    Verify Client Certificate Revocation    : Enabled
    Verify Revocation Using Cached Client Certificate Only    : Disabled
    Usage Check    : Enabled
    Revocation Freshness Time : 0 
    URL Retrieval Timeout   : 0 
    Ctl Identifier          : (null) 
    Ctl Store Name          : (null) 
    DS Mapper Usage    : Disabled
    Negotiate Client Certificate    : Disabled
    

  • 非常感谢任何帮助!

    推荐答案

    我相信它现在对我有用.以下是我为使事情顺利进行而采取的步骤的简要说明:

    I believe its all working for me now. Here is a run down of the steps I took to get things flowing:

    SSL 说明

    SSL &SignalR (Owin WebApplication) 需要将证书绑定到端口.

    SSL & SignalR (Owin WebApplication) requires binding a certificate to a port.

    1. 使用 IIS 生成自签名证书,这应该将证书放入 CERTMGR 中的 LOCAL COMPUTER > Personal > Certificates 文件夹
    2. 在 CERTMGR 中 shift+drag 证书到 LOCAL COMPUTER > Trusted Root Certification Authorities > Certificates 文件夹,应该在那里复制一份
    3. 运行以下命令将 SSL 证书绑定到 0.0.0.0:8080

    1. Use IIS to generate an self-signed cert, this should place the certificate into the LOCAL COMPUTER > Personal > Certificates folder in CERTMGR
    2. In CERTMGR shift+drag certificate to LOCAL COMPUTER > Trusted Root Certification Authorities > Certificates folder, which should make a copy of it there
    3. Run the following command to bind the SSL certificate to 0.0.0.0:8080

    netsh http add sslcert ipport=0.0.0.0:8080 certhash=123456f6790a35f4b017b55d09e28f7ebe001bd appid={12345678-db90-4b66-8b01-88f7af2e36bf} 
    netsh http show urlacl > D:\urlacl.txt
    

    输出:

    Reserved URL            : https://*:8080/ 
    User: SOMEWHERE\Administrator
    Listen: Yes
    Delegate: No
    SDDL: D:(A;;GX;;;S-1-5-21-138209071-46972887-2260295844-1106) 
    

  • 运行以下 NETSH 命令,将端口 8080 的所有 IP 地址保留给 My Service 应用程序 ID 和服务帐户

  • Run the following NETSH command to reserve all IP addresses for port 8080 to the My Service application ID and service account

    netsh http add urlacl url=https://*:8080/ user=SOMEWHERE\Administrator listen=yes
    netsh http show sslcert > D:\sslcert.txt
    

    输出:

    IP:port                 : 0.0.0.0:8080 
    Certificate Hash        : 123456f6790a35f4b017b55d09e28f7ebe001bd
    Application ID          : {12345678-db90-4b66-8b01-88f7af2e36bf} 
    Certificate Store Name  : (null) 
    Verify Client Certificate Revocation    : Enabled
    Verify Revocation Using Cached Client Certificate Only    : Disabled
    Usage Check    : Enabled
    Revocation Freshness Time : 0 
    URL Retrieval Timeout   : 0 
    Ctl Identifier          : (null) 
    Ctl Store Name          : (null) 
    DS Mapper Usage    : Disabled
    Negotiate Client Certificate    : Disabled
    

  • 更新 MyServices.exe.config 文件以使用 https 协议(这些是 appSetting 键,用于在 My Service 启动时动态设置 SignalR 的协议和端口)

  • Update the MyServices.exe.config file to use https protocol (These are appSetting keys used to dynamically set the protocol and port of SignalR when My Service starts)

    <add key="SrProtocol" value="https" />
    <add key="SrPort" value="8080" />
    

  • 使用 NETSTAT START 命令启动我的服务

  • Start the My Service using the NETSTAT START command

    运行以下NETSH命令显示服务状态正在占用注册的url

    Run the following NETSH command to show the service state is occupying the registered url

    netsh http show servicestate > D:\servicestate.txt
    

    输出:

    Server session ID: C300000320000039
    Version: 2.0
    State: Active
    Properties:
        Max bandwidth: 4294967295
        Timeouts:
            Entity body timeout (secs): 120
            Drain entity body timeout (secs): 120
            Request queue timeout (secs): 120
            Idle connection timeout (secs): 120
            Header wait timeout (secs): 120
            Minimum send rate (bytes/sec): 150
    URL groups:
    URL group ID: C600000340000138
        State: Active
        Request queue name: Request queue is unnamed.
        Properties:
            Max bandwidth: inherited
            Max connections: inherited
            Timeouts:
                Timeout values inherited
            Number of registered URLs: 1
            Registered URLs:
                HTTPS://*:8080/
    

  • 我的应用程序不依赖于 IIS,但是一旦我使用 IIS 临时创建绑定到我的 SSL 证书的端口,我的应用程序就开始工作,我能够检查 NETSH 服务状态以查看 IIS 是如何做到的.从那以后,我放弃了 IIS 绑定并浏览了安装说明,但仍然成功.

    My application does NOT depend on IIS, but once I used IIS to temporarily create a port binding to my SSL certificate, my application started to work, and I was able to inspect the NETSH servicestate to see how IIS does it. I have since dropped the IIS binding and ran through the setup notes, and still have success.

    我的 Owing 初创公司看起来像这样:

    My Owing startup looks somethign like this:

    private void configureMessaging()
    {
        string registerUrl = string.Format("{0}://*:{1}", Service.Server.SrProtocol, Service.Server.SrPort);
    
        try
        {
    #if DEBUG
            //System.Diagnostics.Debugger.Launch();
    #endif
            //  Starts an owin web application to host SignalR, using the protocol and port defined.
            WebApp.Start<StartUp>(registerUrl);
        }
        catch (Exception ex)
        {
            Logger.Logs.Log(string.Format("Failed to configure messaging.  Exception: {0}", ex.RecurseInnerException()), LogType.Error);            
    
            if (ex is HttpListenerException || ex.InnerException is HttpListenerException)
            {
                try
                {
                    Process p = new Process();
                    p.StartInfo.UseShellExecute = false;
                    p.StartInfo.RedirectStandardOutput = true;
                    p.StartInfo.FileName = "netsh.exe";
                    p.StartInfo.Arguments = string.Format("netsh http delete urlacl url={0}"
                        , registerUrl
                        );
                    p.Start();
                    p.StandardOutput.ReadToEnd();
                    p.WaitForExit();
                }
                catch (Exception exP)
                {
                    Logger.Logs.Log(string.Format("Failed to delete urlacl {0}.  Exception: {1}"
                        , registerUrl
                        , exP.RecurseInnerException()
                        )
                        , LogType.Error
                        )
                        ;
    
                    retries = 5;
                }
            }
    
        if (retries < 5)
        {
            retries++;
    
            Logger.Logs.Log(string.Format("Attempting to configure messaging again.  Attempt No. {0}", retries), LogType.Warn);
    
            Thread.Sleep(1000);
    
            configureMessaging();
        }
        else
            Logger.Logs.Log(string.Format("Exceeded total number of retries to configure messaging.", retries), LogType.Error);
    
        }
    

    }

    自托管 HubConnetion 实例如下所示:

    And self-hosted HubConnetion instances look like this:

        public IHubProxy MyHubProxy
        {
            get
            {
                if (this._MyHubProxy == null)
                {
                    var connection = new HubConnection(string.Format("{0}://{1}:{2}/"
                        , Settings.GetSetting(Settings.Setting.SrProtocol)
                        , MyHub.GetLocalhostFqdn(null)
                        , Settings.GetSetting(Settings.Setting.SrPort)
                        )
                        )
                        ;
                    this._MyHubProxy = connection.CreateHubProxy("MyHub");
    
                    if (File.Exists("My.cer")
                        && Settings.GetSetting(Settings.Setting.SrProtocol).Equals("https", StringComparison.InvariantCultureIgnoreCase))
                        connection.AddClientCertificate(X509Certificate.CreateFromCertFile("My.cer"));
    
                    connection.Start().Wait();
                }
    
                return this._MyHubProxy;
            }
        }
    

    这里的代码比相关的要多一些,但希望它可能有所帮助!

    There is a little more code here than relevant, but hopefully it may be of help!

    这篇关于具有自签名 SSL 和自托管的 SignalR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆