SignalR具有自签名SSL和自主机

时间:2013-08-09 15:50:37

标签: ssl signalr

在研究中试过我的运气,但到目前为止还没有快乐。

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

我的应用程序在http上工作得很好,但是当Owin WebApplication开始使用https时,客户端会重复断开连接。

以下是我使用SSL配置SignalR所做的工作。

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

    netsh http add sslcert ipport=0.0.0.0:8080 certhash=123456f6790a35f4b017b55d09e28f7ebe001bd appid={12345678-db90-4b66-8b01-88f7af2e36bf}
    
  5. 在自托管HubConnection实例中添加了代码,以便像这样添加导出的SSL(尽管这不重要,因为它是无法连接的客户端):

    if (File.Exists("MyCert.cer") 
        && Settings.GetSetting(Settings.Setting.SrProtocol).Equals("https", StringComparison.InvariantCultureIgnoreCase))
            connection.AddClientCertificate(X509Certificate.CreateFromCertFile("MyCert.cer"));
    
  6. 使用https启动Owin WebApplication(这应该在http.sys中创建绑定)

    string registerUrl = string.Format("{0}://SOME.WHERE.COM:{1}", Service.Server.SrProtocol, Service.Server.SrPort);
    WebApp.Start<StartUp>(registerUrl);
    
  7. 在SignalR 2.0文档中,它说:

      

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

    当我浏览到网址http://SOME.WHERE.COM:8080/signalr/hubs时,我成功收到了驱动SignalR的JavaScript。

    当我浏览到URL https://SOME.WHERE.COM:8080/signalr/hubs时,我没有成功,我收到了“使用FF重置了与服务器的连接”。

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

    • NETSH SHOW表示网址已注册

      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:

      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
      

    非常感谢任何帮助!

1 个答案:

答案 0 :(得分:17)

我相信它现在对我有用。这是我为了让事情顺利而采取的步骤:

SSL说明

SSL&amp; SignalR(Owin WebApplication)要求将证书绑定到端口。

  1. 使用IIS生成自签名证书,这应该将证书放入LOCAL COMPUTER&gt;个人&gt; CERTMGR中的证书文件夹
  2. 在CERTMGR中移位+拖动证书到LOCAL COMPUTER&gt;受信任的根证书颁发机构&gt;证书文件夹,应该在那里复制它
  3. 运行以下命令将SSL证书绑定到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) 
    
  4. 运行以下NETSH命令,将端口8080的所有IP地址保留为“我的服务”应用程序ID和服务帐户

    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
    
  5. 更新MyServices.exe.config文件以使用https协议(这些是appSetting键,用于在My Service启动时动态设置SignalR的协议和端口)

    <add key="SrProtocol" value="https" />
    <add key="SrPort" value="8080" />
    
  6. 使用NETSTAT START命令启动我的服务

  7. 运行以下NETSH命令以显示服务状态占用已注册的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/
    
  8. 我的应用程序不依赖于IIS,但是一旦我使用IIS临时创建绑定到我的SSL证书的端口,我的应用程序就开始工作了,我能够检查NETSH服务状态以查看IIS是如何做到的。我已经放弃了IIS绑定并完成了设置说明,但仍然取得了成功。

    My Owing的创业公司看起来像这样:

    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实例如下所示:

        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;
            }
        }
    

    这里有一些代码而不是相关代码,但希望它可能有所帮助!