研究で運試しをしましたが、今のところ喜びはありません。
SignalR javascriptクライアントを、自己署名SSL証明書にバインドする自己ホスト型SignalRWindowsサービスに接続したいと思います。
私のアプリケーションはhttp上で非常にうまく機能しますが、Owin WebApplicationがhttpsの使用を開始すると、クライアントは繰り返し切断されます。
これが、SSLを使用してSignalRを構成するために行ったことです。
NETSHコマンドを実行してSSLをポート8080にバインドしました
netsh http add sslcert ipport=0.0.0.0:8080 certhash=123456f6790a35f4b017b55d09e28f7ebe001bd appid={12345678-db90-4b66-8b01-88f7af2e36bf}
セルフホストのHubConnectionインスタンスに、このようにエクスポートされたSSLを追加するコードを追加しました(ただし、接続できないのはクライアントであるため、これは問題ではありません)。
if (File.Exists("MyCert.cer")
&& Settings.GetSetting(Settings.Setting.SrProtocol).Equals("https", StringComparison.InvariantCultureIgnoreCase))
connection.AddClientCertificate(X509Certificate.CreateFromCertFile("MyCert.cer"));
Httpsを使用してOwinWebApplicationを起動します(これにより、http.sysにバインディングが作成されます)
string registerUrl = string.Format("{0}://SOME.WHERE.COM:{1}", Service.Server.SrProtocol, Service.Server.SrPort);
WebApp.Start<StartUp>(registerUrl);
SignalR 2.0のドキュメントには、次のように記載されています。
Webサーバーを起動するには、WebApplication.Start(endpoint)を呼び出します。これで、ブラウザでエンドポイント/シグナル/ハブに移動できるようになります。
URLを参照すると http://SOME.WHERE.COM:8080/signalr/hubs SignalRを駆動するJavaScriptを正常に受信しています。
URLを参照すると https://SOME.WHERE.COM:8080/signalr/hubs 失敗し、FFを使用して「サーバーへの接続がリセットされました」というメッセージが表示されます。
私が考慮したいくつかの追加のポイント:
NETSH SHOWは、URLが登録されていることを示します
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
どんな助けでも大歓迎です!
私はそれがすべて私のために今働いていると信じています。これは私が物事を流すために取ったステップの要約です:
SSLノート
SSL&SignalR(Owin WebApplication)では、証明書をポートにバインドする必要があります。
次のコマンドを実行して、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)
次の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
Httpsプロトコルを使用するようにMyServices.exe.configファイルを更新します(これらは、マイサービスの開始時にSignalRのプロトコルとポートを動的に設定するために使用されるappSettingキーです)
<add key="SrProtocol" value="https" />
<add key="SrPort" value="8080" />
NETSTATSTARTコマンドを使用してマイサービスを開始します
次の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/
私のアプリケーションはIISに依存していませんが、IISを使用してSSL証明書へのポートバインディングを一時的に作成すると、アプリケーションが機能し始め、NETSHサービス状態を調べて確認することができました。どのようにIISそれを行います。それ以来、IISバインディングを削除し、セットアップノートを実行しましたが、それでも成功しています。
私の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;
}
}
ここには関連するよりも少し多くのコードがありますが、うまくいけばそれが役立つかもしれません!