私は数年前に、サードパーティのSOAPWebサービスを含むいくつかのソースからのデータを処理するWindowsサービスを作成しました。サードパーティから提供されたクライアント証明書を使用して、このWebサービスで認証されました。これは、その時点では正常に機能し、デプロイされた元のマシンでも正常に機能していますが、現在、接続の試行で次のメッセージを含む例外がスローされる新しいマシンに移行しています。
クライアント認証スキーム「匿名」でHTTPリクエストが禁止されました
同じことが私の開発マシンでも起こっています。これは、Webサービスへの接続を構成するコードです。
Friend Shared Function GetProperlyConfiguredConnection() As SEMOService.MIWebServiceClient
' Ensure that the settings are valid
ValidateSettings()
Dim destAddress As New System.ServiceModel.EndpointAddress(Url)
' The service uses SOAP 1.1 which is what BasicHttpBinding uses. WSHttpBinding uses SOAP 1.2.
'Dim destBinding As New System.ServiceModel.WSHttpBinding
Dim destBinding As New System.ServiceModel.BasicHttpBinding
With destBinding
.CloseTimeout = New TimeSpan(0, 1, 0)
.OpenTimeout = New TimeSpan(0, 1, 0)
.ReceiveTimeout = New TimeSpan(0, 10, 0)
.SendTimeout = New TimeSpan(0, 1, 0)
.BypassProxyOnLocal = False
.HostNameComparisonMode = ServiceModel.HostNameComparisonMode.StrongWildcard
.MaxBufferPoolSize = 524288
.MaxReceivedMessageSize = 2147483647
.MessageEncoding = ServiceModel.WSMessageEncoding.Text
.TextEncoding = System.Text.Encoding.UTF8
.UseDefaultWebProxy = True
.AllowCookies = False
With .ReaderQuotas
.MaxDepth = 32
.MaxStringContentLength = 2147483647
.MaxArrayLength = 50000000
.MaxBytesPerRead = 4096
.MaxNameTableCharCount = 16384
End With
.Security.Mode = ServiceModel.BasicHttpSecurityMode.Transport
.Security.Transport.ClientCredentialType = ServiceModel.HttpClientCredentialType.Certificate
End With
Dim wcfService As New SEMOService.MIWebServiceClient(destBinding, destAddress)
' Load the certificate from the specified file.
Dim keyData As Byte()
Dim keyFileInfo As New IO.FileInfo(SEMOServiceSettings.KeyFilePath)
Dim keyFileReader As New IO.BinaryReader(New IO.FileStream(SEMOServiceSettings.KeyFilePath, IO.FileMode.Open, IO.FileAccess.Read))
keyData = keyFileReader.ReadBytes(keyFileInfo.Length)
keyFileReader.Close()
Dim cert As New X509Certificates.X509Certificate2
cert = New X509Certificates.X509Certificate2(keyData, SEMOServiceSettings.KeyFilePassword)
wcfService.ClientCredentials.ClientCertificate.Certificate = cert
Return wcfService
End Function
これは実際にはWCFWebサービスではありませんが、WSDLからクライアントコードを自動生成するときにVisualStudioは気にしなかったようです。クライアント証明書は、証明書ストアからではなくファイルからロードされます。同じ証明書ファイルがすべてのマシンで使用されており、コードをステップ実行すると正常にロードされているように見えます。
動作するマシンからのリクエストと、WireSharkを使用する開発マシンからのリクエストを比較したところ、クライアント証明書がハンドシェイクに含まれていないようです。
これは、動作するマシン上のリクエストからの対応するパケットです。
WCF、SOAP、暗号化については理解できないことがたくさんあるので、この動作をもたらすために環境について何が異なる可能性があるのか、そしてそれを修正するために何を変更する必要があるのかについて少し迷っています。
この質問は関連しているようですが、コードを介してプロパティにアクセスできないようでRequireClientCertificate
、app.configを使用してバインディングを構成していません。
サーバー証明書のカスタム検証を実行するために、ServicePointManagerクラスにコールバックを追加することができます。基本クライアントクラスまたはバインディングは、サーバーに送信する前にクライアント証明書の検証を実行しますか?もしそうなら、サーバー証明書の検証と同じ方法でそのプロセスに介入して、何が起こっているのかを確認する方法はありますか?