C# WCF-找不到X509SecurityToken的令牌身份验证程序

C# WCF-找不到X509SecurityToken的令牌身份验证程序,c#,wcf,soap,soap-client,C#,Wcf,Soap,Soap Client,我正在尝试调用第三方Web服务,现在我可以在服务跟踪查看器中看到来自服务器的响应。但是,我一直从.NET收到一个异常: 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. My app.

我正在尝试调用第三方Web服务,现在我可以在服务跟踪查看器中看到来自服务器的响应。但是,我一直从.NET收到一个异常:

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.
My app.config如下所示(用占位符替换指纹):

我是否可以在某个位置添加x508SecurityToken处理程序,或者忽略此错误(这样做安全吗)

异常堆栈跟踪:

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)

上述内容是否意味着它是服务器端?

您的
findValue
属性的值都不正确。您应该将相应客户端证书的特定指纹值放入
app.config

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


我还要再次检查客户端X509证书是否正常需要,它们仅用于服务器端操作。

您的
findValue
属性的值都不正确。您应该将相应客户端证书的特定指纹值放入
app.config

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

我还将再次检查客户端X509证书是否正常需要,它们仅用于服务器端操作。

我找到了解决方案:

  • authenticationMode=“CertificateOverTransport”
    更改为
    authenticationMode=“MutualCertificate”
  • 使用
    MessageSecurityVersion.wssecurity10wstrustfebruary2005wssecurityconversationfebruary2005wssecuritypolicy11basicsecurityprofile10
  • 在生成的客户端中,将
    ProtectionLevel=ProtectionLevel.Sign
    添加到
    servicecontract属性中。这样可以避免对主体进行加密
  • 我还没有全部完成,但我相信这只是从提供商那里获得正确证书的问题

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

    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。这不应用于生产。

    我找到了解决方案:

  • authenticationMode=“CertificateOverTransport”
    更改为
    authenticationMode=“MutualCertificate”
  • 使用
    MessageSecurityVersion.wssecurity10wstrustfebruary2005wssecurityconversationfebruary2005wssecuritypolicy11basicsecurityprofile10
  • 在生成的客户端中,将
    ProtectionLevel=ProtectionLevel.Sign
    添加到
    servicecontract属性中。这样可以避免对主体进行加密
  • 我还没有全部完成,但我相信这只是从提供商那里获得正确证书的问题

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

    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。这不应在生产中使用。

    它们是占位符。。已正确找到证书-我收到服务器的响应。我没有收到提供商的证书,所以我从Chrome上获得了证书。这可能是个问题吗?异常消息似乎并不表示证书错误,而是表示它无法验证响应中的令牌。您是如何向服务添加引用的?通常情况下,VS中的添加服务引用向导会在很短的时间内获得WCF配置。。。正如我所说,客户端证书并不常用。您在没有客户端证书的情况下尝试过吗?我使用向导添加了它。服务提供商使用基于som SAP的服务,该服务不包括wsdl中的所有信息(缺少安全部分)。是的,它使用客户端证书进行身份验证-没有用户名/密码。它们是占位符。。已正确找到证书-我收到服务器的响应。我没有收到提供商的证书,所以我从Chrome上获得了证书。这可能是个问题吗?异常消息似乎并不表示证书错误,而是表示它无法验证响应中的令牌。您是如何向服务添加引用的?通常情况下,VS中的添加服务引用向导会在很短的时间内获得WCF配置。。。正如我所说,客户端证书并不常用。您在没有客户端证书的情况下尝试过吗?我使用向导添加了它。服务提供商使用基于som SAP的服务,该服务不包括wsdl中的所有信息(缺少安全部分)。是的,它使用客户端证书进行身份验证-没有用户名/密码。
    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");