1

サーバー証明書を使用する WCF サービスがあります。証明書は、当社の内部認証局によって署名されています。ルート証明書は自己署名されており、AD経由ですべてのドメイン コンピューターに配布されます。このサービスに接続する多くのプログラム (約 200 台の PC で約 50 個のアプリケーション) を構築してデプロイしましたが、1 つのサーバー (これを BROKENHOST と呼びます) を除いて、すべて期待どおりに動作します。この特定のサーバー (Windows Server 2003 標準サーバー) では、プログラムがサービスに接続しようとするたびに、具体的には SecurityNegotiationExeption をスローします (名前は会社を保護するために変更されています)。

System.ServiceModel.Security.SecurityNegotiationException: X.509 証明書 CN=server.sub.domain.com、OU=sub、O=domain.com、L=どこか、S=カリフォルニア、C=US チェーンの構築に失敗しました。使用された証明書には、検証できない信頼チェーンがあります。証明書を置き換えるか、certificateValidationMode を変更してください。失効サーバーがオフラインのため、失効機能は失効を確認できませんでした。
---> System.IdentityModel.Tokens.SecurityTokenValidationException: X.509 証明書 CN=server.sub.domain.com、OU=sub、O=domain.com、L=どこか、S=カリフォルニア、C=US チェーン ビルディング失敗した。使用された証明書には、検証できない信頼チェーンがあります。証明書を置き換えるか、certificateValidationMode を変更してください。失効サーバーがオフラインのため、失効機能は失効を確認できませんでした。

WCF サービスで使用される証明書は、IIS でも使用されます。ここで奇妙なのは、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 に何か問題があることを確信しています。リモート デバッガーでコードを実行してみましたが、まだわかっていないことは何も得られませんでした。

他に試してみるべき提案があれば、教えてください。

PSが役立つ場合に備えて、スタックトレースは次のとおりです。

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()
4

0 に答える 0