【问题标题】:Programmatically call WCF: identity check failed以编程方式调用 WCF:身份检查失败
【发布时间】:2019-03-06 10:37:44
【问题描述】:

我正在从 App.config 迁移到以编程方式调用具有客户端证书身份验证/身份的 WCF 服务。新代码是 .NET Core,但测试控制台应用的目标框架已设置为 net472,以便在 Azure Kudu 中运行。

我到处搜索,但无法摆脱此错误消息。

错误:

未处理的异常:System.ServiceModel.Security.MessageSecurityException:传出消息的身份检查失败。 'net.tcp://myserver:1001/MyServiceRelay/MyServiceRelay.svc' 目标端点的预期身份是 'identity(http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty:http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint)'。

服务器堆栈跟踪: 在 System.ServiceModel.Security.IdentityVerifier.EnsureIdentity(端点地址 serviceReference,AuthorizationContext 授权上下文,字符串 errorString) 在 System.ServiceModel.Security.MessageSecurityProtocol.EnsureOutgoingIdentity(SecurityToken token, SecurityTokenAuthenticator 验证器)

App.config:

<endpoint name="MyEndpoint"
                address="[PLACEHOLDER]"
                binding="netTcpBinding"
                bindingConfiguration="NetTcpAzureBinding"
                behaviorConfiguration="AzureCertificateBehavior"
                contract="MyCalledService">
        <identity>
          <certificate encodedValue="[PLACEHOLDER]" />
        </identity>
 </endpoint>

<netTcpBinding>
        <binding name="NetTcpAzureBinding" maxReceivedMessageSize="20485760">
          <readerQuotas maxArrayLength="20485760" maxStringContentLength="20485760" />
          <security mode="Message">
            <message clientCredentialType="Certificate" />
          </security>
        </binding>
 </netTcpBinding>

<behavior name="AzureCertificateBehavior">
          <clientCredentials>
            <clientCertificate storeName="My" storeLocation="CurrentUser" x509FindType="FindByThumbprint" findValue="[PLACEHOLDER]" />
            <serviceCertificate>
              <authentication certificateValidationMode="None" revocationMode="NoCheck" />
            </serviceCertificate>
          </clientCredentials>
 </behavior>

代码等效:

// My FindCertificate method performs a lookup by thumbprint, exactly the same code that below when using "SetCertificate".
X509Certificate2 certificate = Common.FindCertificate(settings.CertificateThumbprint);
        var binding = new NetTcpBinding
        {
            // custom constant
            MaxReceivedMessageSize = Common.MaxReceivedMessageSize
        };
        // custom constant
        binding.ReaderQuotas.MaxArrayLength = Common.MaxArrayLength;
        // custom constant
        binding.ReaderQuotas.MaxStringContentLength = Common.MaxStringContentLength;

        binding.Security.Mode = SecurityMode.Message;
        binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;

        var endpoint = new EndpointAddress(new Uri(settings.MailService.EndpointAddress), EndpointIdentity.CreateX509CertificateIdentity(certificate));

        _channelFactory = new ChannelFactory<IMailService>(binding, endpoint);

        _channelFactory.Credentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByThumbprint, settings.CertificateThumbprint);
        _channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
        _channelFactory.Credentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;

怎么了?感谢您的想法。

【问题讨论】:

    标签: c# wcf wcf-binding wcf-security


    【解决方案1】:

    好吧,没有什么“错误”,但错误消息并不令人满意。一旦我得到它,我只需要更换:

    EndpointIdentity.CreateX509CertificateIdentity(certificate)
    

    作者:

    EndpointIdentity.CreateDnsIdentity(settings.MailService.EndpointDns)
    

    在端点身份初始化中。并且期望值在错误消息中......

    帮助我的是设置一个通道工厂,它通过将经典的 .config 文件读取到配置类来进行初始化:

            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = "MailService.config";
            Configuration newConfiguration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
    
            _channelFactory = new ConfigurationChannelFactory<IMailService>("MyEndpoint", newConfiguration, new EndpointAddress("net.tcp://myserver:1001/MyServiceRelay/MyServiceRelay.svc"));
    

    (嗯,这个调用endpoint没有成功,只是给个提示)。

    仍然悬而未决的问题:为什么经典配置在没有抱怨端点 DNS 的情况下工作?我又检查了一遍。我读到了 2010 年有关此安全检查的内容(防止网络钓鱼)。也很有用:https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/service-identity-and-authentication

    欢迎评论。

    【讨论】:

      猜你喜欢
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-27
      • 2011-11-22
      • 1970-01-01
      相关资源
      最近更新 更多