WCF – 找不到X509SecurityToken的令牌validation器

我正在尝试调用第三方Web服务,我已经到了能够在服务跟踪查看器中实际看到服务器响应的地步。 但是,我不断从.NET获得exception:

Cannot find a token authenticator for the 'System.IdentityModel.Tokens.X509SecurityToken' token type. Tokens of that type cannot be accepted according to current security settings. 

我的app.config看起来像这样(用占位符替换了Thumbprints):

        <defaultCertificate findValue="" x509FindType="FindByThumbprint" storeLocation="CurrentUser" storeName="TrustedPeople"/>  <clientCertificate findValue="" x509FindType="FindByThumbprint"/>                  

现在,我已经尝试了有关此exception的所有内容。

  1. authenticationMode设置为MutualCertificate :服务器响应404
  2. 设置allowSerializedSigningTokenOnReply :无变化

来自服务器的响应包含:

      

我可以在某处添加x508SecurityToken处理程序,否则忽略此错误(这样做是否安全)

exception堆栈跟踪:

 Server stack trace: at System.ServiceModel.Security.ReceiveSecurityHeader.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver, IList`1 allowedTokenAuthenticators, SecurityTokenAuthenticator& usedTokenAuthenticator) at System.ServiceModel.Security.ReceiveSecurityHeader.ReadToken(XmlDictionaryReader reader, Int32 position, Byte[] decryptedBuffer, SecurityToken encryptionToken, String idInEncryptedForm, TimeSpan timeout) at System.ServiceModel.Security.ReceiveSecurityHeader.ExecuteFullPass(XmlDictionaryReader reader) at System.ServiceModel.Security.StrictModeSecurityHeaderElementInferenceEngine.ExecuteProcessingPasses(ReceiveSecurityHeader securityHeader, XmlDictionaryReader reader) at System.ServiceModel.Security.ReceiveSecurityHeader.Process(TimeSpan timeout, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy) at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessageCore(Message& message, TimeSpan timeout) at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout) at System.ServiceModel.Security.SecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates) at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout) at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout) at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) 

以上是否意味着它是服务器端?

我找到了解决方案:

  1. authenticationMode="CertificateOverTransport"更改为authenticationMode="MutualCertificate"
  2. 使用MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10
  3. 在生成的客户端中,将ProtectionLevel = ProtectionLevel.Sign添加到ServiceContractAttribute 。 这避免了身体加密。

我仍然没有完全通过,但我认为这只是从提供商那里获得正确的证书。

对于其他人,以下是我创建代理的方式:

 var binding = new BasicHttpsBinding(); binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; var address = new EndpointAddress(new Uri("https://xxx/yyy/someService/")); binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate; var securityElement = SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10, true); securityElement.IncludeTimestamp = true; var customBinding = new CustomBinding(binding); customBinding.Elements.Insert(0, securityElement); var client = new ReportGasClient(customBinding, address); client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByThumbprint, "BCC3929F9C115D4BCA1C697E2557B7FC7D6C8C8C"); client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.CurrentUser, StoreName.TrustedPeople, X509FindType.FindByThumbprint, "87C3B5EE3913937459D2FFBF105ADBD1A578E823"); 

请注意我只在沙箱环境中将ValidationMode设置为None。 这绝不应该用于生产。

您的findValue属性值都不正确。 您应该在app.config为相应的客户端证书添加特定的指纹值。

您可以通过证书MMC加载项查看证书指纹值。

我还要仔细检查客户端X509证书是否正常,只需要服务器端操作。