WCF客户端SecurityNegotiationException

时间:2014-02-04 19:21:00

标签: .net wcf ssl-certificate windows-server-2003 certificate-authority

我有一个使用服务器证书的WCF服务。证书由我们的内部证书颁发机构签名。根证书是自签名的,并通过AD分发给所有域计算机。我们已经构建并部署了许多附加到此服务的程序(大约50台应用程序,大约200台PC),它们都按预期工作,除了一台服务器(我将其称为BROKENHOST)。在此特定服务器(Windows Server 2003标准服务器)上,只要程序尝试连接到该服务,它就会抛出SecurityNegotiationExeption(具体名称已更改以保护公司):

System.ServiceModel.Security.SecurityNegotiationException:X.509证书CN = server.sub.domain.com,OU = sub,O = domain.com,L = Somewhere,S = California,C = US chain building failed。使用的证书具有无法验证的信任链。替换证书或更改certificateValidationMode。由于吊销服务器处于脱机状态,吊销功能无法检查吊销。
---> System.IdentityModel.Tokens.SecurityTokenValidationException:X.509证书CN = server.sub.domain.com,OU = sub,O = domain.com,L =某处,S =加利福尼亚州,C =美国连锁建筑失败。使用的证书具有无法验证的信任链。替换证书或更改certificateValidationMode。由于吊销服务器处于脱机状态,吊销功能无法检查吊销。

IIS也使用WCF服务使用的证书。这里奇怪的部分是,如果我在BROKENHOST上打开IE并放入https://server.sub.domain.com,页面打开就好了,证书链说OK。所以,我不确定为什么IE可以使用证书,但Windows应用程序失败。

客户端连接本身是通过channelfactory创建的,如下所示:

System.ServiceModel.Channels.AddressHeader[] addressHeader = new System.ServiceModel.Channels.AddressHeader[] {
            System.ServiceModel.Channels.AddressHeader.CreateAddressHeader("CUSTOM_USER_ID", "CUSTOM", m_user_id),
            System.ServiceModel.Channels.AddressHeader.CreateAddressHeader("CUSTOM_SOURCE_NAME", "CUSTOM", m_source_name)
};

string strUri = string.Format("net.tcp://{0}:{1}/{2}", m_strServer[strRegKey], m_strPort[strRegKey], strAddress);
System.ServiceModel.EndpointAddress epa = new System.ServiceModel.EndpointAddress(new Uri(strUri), EndpointIdentity.CreateDnsIdentity(m_strServer[strRegKey]), addressHeader);

NetTcpBinding binding = new NetTcpBinding();
binding.OpenTimeout = TimeSpan.FromSeconds(15);
//binding.OpenTimeout = TimeSpan.FromTicks(1);
binding.ReaderQuotas.MaxArrayLength = Int32.MaxValue; // ChunkSizeSingleton.DOWNLOAD_CHUNK_MAX_SIZE;
binding.ReaderQuotas.MaxBytesPerRead = Int32.MaxValue;
binding.ReaderQuotas.MaxDepth = Int32.MaxValue;
binding.ReaderQuotas.MaxNameTableCharCount = Int32.MaxValue;
binding.ReaderQuotas.MaxStringContentLength = Int32.MaxValue;
binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
binding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.ReliableSession.Enabled = true;
binding.ReliableSession.Ordered = true;
binding.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(10);

binding.MaxReceivedMessageSize = Int32.MaxValue; // (long)(ChunkSizeSingleton.DOWNLOAD_CHUNK_MAX_SIZE * 1.3);

ChannelFactory<T> channelFactory = new ChannelFactory<T>(binding, epa);

channelFactory.Credentials.UserName.UserName = m_user_name;
channelFactory.Credentials.UserName.Password = m_user_password;
channelFactory.Credentials.SupportInteractive = false;

foreach (OperationDescription od in channelFactory.Endpoint.Contract.Operations)
{
    DataContractSerializerOperationBehavior ser = od.Behaviors.Find<DataContractSerializerOperationBehavior>();

    ser.MaxItemsInObjectGraph = Int32.MaxValue;
}

同样,我们确信服务器设置正确,并且BROKENHOST存在问题。我尝试使用远程调试器运行代码,但这并没有让我得到任何我们不知道的东西。

如果有人对我有任何其他建议,请告诉我。

P.S。如果它有帮助,这里是stacktrace:

at System.IdentityModel.Selectors.X509CertificateChain.Build(X509Certificate2 certificate)
at System.IdentityModel.Selectors.X509CertificateValidator.ChainTrustValidator.Validate(X509Certificate2 certificate)
at System.IdentityModel.Selectors.X509SecurityTokenAuthenticator.ValidateTokenCore(SecurityToken token)
at System.IdentityModel.Selectors.SecurityTokenAuthenticator.ValidateToken(SecurityToken token)
at System.ServiceModel.Channels.SslStreamSecurityUpgradeInitiator.ValidateRemoteCertificate(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
at System.Net.Security.SslStream.userCertValidationCallbackWrapper(String hostName, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
at System.Net.Security.SecureChannel.VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback)
at System.Net.Security.SslState.CompleteHandshake()
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
at System.ServiceModel.Channels.SslStreamSecurityUpgradeInitiator.OnInitiateUpgrade(Stream stream, SecurityMessageProperty& remoteSecurity)
   --- End of inner exception stack trace ---
服务器堆栈跟踪:
at System.ServiceModel.Channels.SslStreamSecurityUpgradeInitiator.OnInitiateUpgrade(Stream stream, SecurityMessageProperty& remoteSecurity)
at System.ServiceModel.Channels.StreamSecurityUpgradeInitiatorBase.InitiateUpgrade(Stream stream)
at System.ServiceModel.Channels.ConnectionUpgradeHelper.InitiateUpgrade(StreamUpgradeInitiator upgradeInitiator, IConnection& connection, ClientFramingDecoder decoder, IDefaultCommunicationTimeouts defaultTimeouts, TimeoutHelper& timeoutHelper)
at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
在[0]处重新抛出异常:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.ServiceModel.ICommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.ClientSecurityChannel`1.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ReliableChannelBinder`1.ChannelSynchronizer.SyncWaiter.TryGetChannel()
at System.ServiceModel.Channels.ReliableChannelBinder`1.ChannelSynchronizer.SyncWaiter.TryWait(TChannel& channel)
at System.ServiceModel.Channels.ReliableChannelBinder`1.ChannelSynchronizer.TryGetChannel(Boolean canGetChannel, Boolean canCauseFault, TimeSpan timeout, MaskingMode maskingMode, TChannel& channel)
at System.ServiceModel.Channels.ReliableChannelBinder`1.Send(Message message, TimeSpan timeout, MaskingMode maskingMode)
at System.ServiceModel.Channels.SendReceiveReliableRequestor.OnRequest(Message request, TimeSpan timeout, Boolean last)
at System.ServiceModel.Channels.ReliableRequestor.Request(TimeSpan timeout)
at System.ServiceModel.Channels.ClientReliableSession.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ClientReliableDuplexSessionChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open()

0 个答案:

没有答案