我真的希望这里有人能提供帮助。在我的问题开始之前,我还要声明我不是 .NET 专家,并且在 Web 服务和 SSL/安全问题方面的经验很少。
我正在尝试创建一个 VB .NET 控制台应用程序来使用托管在 Apache 服务器上的基于 Java 的 Web 服务。正在通过 SSL 进行通信。需要客户端证书(由 Web 服务提供商提供)并且还需要基本身份验证(用户名/密码)才能使用该服务。
从提供的 PFX 文件安装证书(使用 certmgr.mgr),并将证书存储在我的个人存储和受信任的根存储中。我没有勾选强加密的任何复选框(所有内容都使用默认值)。
我使用提供的 WSDL 文件为服务创建了一个代理类。驻留在其服务器上的 WSDL 不正确,不能用于 .NET 中的早期绑定(bind)。我使用“SVCUTIL *.wsdl/language:VB”创建了代理类。
尝试从服务调用公开的方法之一时出现以下错误:
向“https://webservice-url?WSDL”发出 HTTP 请求时发生错误。这可能是由于在 HTTPS 情况下服务器证书未正确配置为 HTTP.SYS。这也可能是由于客户端和服务器之间的安全绑定(bind)不匹配造成的。
如果我从异常快照中查看 InnerException,我会看到以下内容:
底层连接已关闭:发送时发生意外错误。
这是我用来初始化客户端和连接到 Web 服务的代码:
'Override server certificate callback
Dim oCertOverride As New CertificateOverride
ServicePointManager.ServerCertificateValidationCallback = _
AddressOf oCertOverride.RemoteCertificateValidationCallback
'Set WS binding
Dim binding As WSHttpBinding = New WSHttpBinding
binding.Security.Mode = SecurityMode.Transport
binding.Security.Transport.ClientCredentialType = _
HttpClientCredentialType.Certificate
'Set endpoint address
Dim address As EndpointAddress = _
New EndpointAddress("https://webservice-url?WSDL")
'Create web service client
Dim ws As wsclient = New wsclient(binding, address)
'Set web service client certificate
ws.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, _
StoreName.My, X509FindType.FindBySubjectName, "cert-subject-name")
'Set username and password for server authentication
ws.ClientCredentials.UserName.UserName = "username"
ws.ClientCredentials.UserName.Password = "password"
'Make test call to web service
ws.HelloWord()
我还应该提到,我可以使用 Firefox 和 IE 连接到 Web 服务并查看所有暴露的方法。
我一直在网上寻找帮助。大多数对人们有用的快速修复都没有帮助。我试过绑定(bind)设置,但这只会导致各种错误,比如无法使用“匿名”用户帐户连接到 Web 服务。
我真的很迷茫。任何提示或帮助将不胜感激。
感谢您的宝贵时间。
最佳答案
您的绑定(bind)似乎过于复杂(设置证书。)
尝试将其创建为一个类:
Imports System.ServiceModel
Public Class MyBinding
Public Property _Binder As BasicHttpBinding
Public Sub New(ByVal BinderName As String)
_Binder = New BasicHttpBinding()
_Binder.Name = BinderName
_Binder.CloseTimeout = TimeSpan.FromMinutes(10)
_Binder.OpenTimeout = TimeSpan.FromMinutes(10)
_Binder.ReceiveTimeout = TimeSpan.FromMinutes(10)
_Binder.SendTimeout = TimeSpan.FromMinutes(10)
_Binder.AllowCookies = False
_Binder.BypassProxyOnLocal = False
_Binder.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard
_Binder.MaxBufferSize = 655360
_Binder.MaxBufferPoolSize = 655360
_Binder.MaxReceivedMessageSize = 655360
_Binder.MessageEncoding = WSMessageEncoding.Text
_Binder.TextEncoding = System.Text.Encoding.UTF8
_Binder.TransferMode = TransferMode.Buffered
_Binder.UseDefaultWebProxy = True
_Binder.ReaderQuotas.MaxDepth = 32
_Binder.ReaderQuotas.MaxStringContentLength = 8192
_Binder.ReaderQuotas.MaxArrayLength = 655360
_Binder.ReaderQuotas.MaxBytesPerRead = 4096
_Binder.ReaderQuotas.MaxNameTableCharCount = 16384
_Binder.Security.Transport.ClientCredentialType = HttpClientCredentialType.None
_Binder.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None
_Binder.Security.Transport.Realm = ""
_Binder.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName
_Binder.Security.Message.AlgorithmSuite = Security.SecurityAlgorithmSuite.Default
_Binder.Security.Mode = BasicHttpSecurityMode.Transport
System.Net.ServicePointManager.Expect100Continue = False
End Sub
下课
然后,调用WS如下:
Dim binding As New MyBinding("some_name")
'Set endpoint address
Dim address As EndpointAddress = _
New EndpointAddress("https://webservice-url?WSDL")
'Create web service client
Dim ws As wsclient = New wsclient(binding._Binder, address)
我的电脑上没有安装 Visual Studio,所以如果上面的代码有错误,请告诉我,我会检查。
关于vb.net - "The underlying connection was closed: An unexpected error occurred on a send."(Java/Apache SSL 加密 Web 服务的 VB .NET 客户端),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4820120/