我有一个解决方案,在一个Window Service中包含2个WCF服务Selfhosted,一个用于常规http,一个用于https。客户端可以连接到http服务,但在连接到https服务时,我得到:
发出HTTP请求时发生错误 https://192.168.130.29:44390/MyAppService/SSl。这可能是由于 服务器证书配置不正确的事实 HTTPS案例中的HTTP.SYS。这也可能是由于不匹配造成的 客户端和服务器之间的安全绑定。
我已经检查了URL及其正确。
首先我在客户端激活WCF跟踪,我可以看到这个
接收连接上的字节https://192.168.130.29:44390/MyAppService/Sll
<ExceptionType>System.ServiceModel.CommunicationException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>An error occurred while making the HTTP request to https://192.168.130.29:44390/MyAppService/Sll. This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelAsyncRequest.OnGetResponse(IAsyncResult result)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.CompleteCallback(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.HttpWebRequest.SetResponse(Exception E)
at System.Net.HttpWebRequest.CheckWriteSideResponseProcessing()
at System.Net.ConnectStream.ProcessWriteCallDone(ConnectionReturnResult returnResult)
at System.Net.HttpWebRequest.WriteCallDone(ConnectStream stream, ConnectionReturnResult returnResult)
at System.Net.ConnectStream.CallDone(ConnectionReturnResult returnResult)
at System.Net.ConnectStream.IOError(Exception exception, Boolean willThrow)
at System.Net.ConnectStream.HandleWriteHeadersException(Exception e, WebExceptionStatus error)
at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.TlsStream.ResumeIOWorker(Object result)
at System.Net.TlsStream.WakeupPendingIO(IAsyncResult ar)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.CompleteCallback(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<ExceptionString>System.ServiceModel.CommunicationException: An error occurred while making the HTTP request to https://192.168.130.29:44390/MyAppService/Sll. This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)
at System.Net.PooledStream.EndWrite(IAsyncResult asyncResult)
at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
--- End of inner exception stack trace ---</ExceptionString>
<InnerException>
<ExceptionType>System.Net.WebException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>The underlying connection was closed: An unexpected error occurred on a send.</Message>
<StackTrace>
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
</StackTrace>
<ExceptionString>System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)
at System.Net.PooledStream.EndWrite(IAsyncResult asyncResult)
at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)</ExceptionString>
<InnerException>
<ExceptionType>System.IO.IOException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.</Message>
<StackTrace>
at System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)
at System.Net.PooledStream.EndWrite(IAsyncResult asyncResult)
at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
</StackTrace>
<ExceptionString>System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)
at System.Net.PooledStream.EndWrite(IAsyncResult asyncResult)
at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)</ExceptionString>
<InnerException>
<ExceptionType>System.Net.Sockets.SocketException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>An existing connection was forcibly closed by the remote host</Message>
<StackTrace>
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
</StackTrace>
<ExceptionString>System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)</ExceptionString>
<NativeErrorCode>2746</NativeErrorCode>
</InnerException>
</InnerException>
</InnerException>
我打开服务上的WCF跟踪,我得到一个日志,但没有传入消息!?
我已检查过证书是否已安装在服务器上并且证书有效。如果找不到,则https服务永远不会启动。
证书也安装在客户端计算机上,我也可以看到它在那里也有效。
如果我在我的开发计算机上运行此解决方案(服务和客户端),那么它的效果很好!
这可能是服务器上的阻塞端口吗?在此之前我从来没有打开任何端口。
编辑:有关如何在客户端创建channelfactory的代码。
private async Task<ChannelFactory<T>> CreateChannelFactory(LoginTypeBase loginType, MyAppToken token)
{
var service = await _ConsulService.GetServiceBlocking(loginType.MyAppServicesToUse, forceRefresh: true, token: new CancellationTokenSource(TimeSpan.FromSeconds(30)).Token);
if (service == null)
throw new MyAppServiceCommunicationException();
var uri = loginType.GetMyAppClientServiceURL(service.Address, service.Port);
var header = AddressHeader.CreateAddressHeader(nameof(MyAppToken), nameof(MyAppToken), token);
var endpointAddress = new EndpointAddress(uri, header);
ServiceEndpoint serviceEndpoint = null;
if (loginType.LoginType == LoginType.SmartCard || loginType.LoginType == LoginType.UsernamePasswordSecure)
{
var binding = new NetHttpsBinding("netHttpsBinding");
binding.Security.Mode = BasicHttpsSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
serviceEndpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(T)), binding, endpointAddress);
}
else
{
var binding = new NetHttpBinding("netHttpBinding");
serviceEndpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(T)), binding, endpointAddress);
}
serviceEndpoint.EndpointBehaviors.Add(new ProtoEndpointBehavior());
serviceEndpoint.EndpointBehaviors.Add(new CustomMessageInspectorBehavior());
var v = new ChannelFactory<T>(serviceEndpoint);
return v;
}
编辑2: 我可以在事件日志中看到&gt;安全审核在拨打电话时失败。它说:
帐户无法登录失败信息:失败 原因:未知的用户名或密码错误。状态:0xC000006D Sub 状态:0xC0000064进程信息:调用者进程ID:0x22c 调用者进程名称:C:\ Windows \ System32 \ lsass.exe
网络信息:工作站名称:TITAN源网络 地址: - 源端口: -
详细的身份验证信息:登录过程:Schannel 身份验证包:Kerberos过渡服务: - 包名称 (仅限NTLM): - 密钥长度:0
并且
详细的身份验证信息:登录过程:Schannel 身份验证包:Microsoft统一安全协议提供程序 过渡服务: - 包名称(仅限NTLM): - 密钥长度:0
当登录请求失败时会生成此事件。它是生成的 尝试访问的计算机。
主题字段表示本地系统上的帐户 请求登录。这通常是一种服务,如 服务器服务,或Winlogon.exe或本地进程 Services.exe中。
“登录类型”字段指示所请求的登录类型。 最常见的类型是2(交互式)和3(网络)。
“流程信息”字段指示了哪个帐户和流程 系统请求登录。
“网络信息”字段指示远程登录请求的位置 起源。工作站名称并非始终可用,可能会保留 在某些情况下是空白的。