首页 > 解决方案 > WCF 服务中未调用自定义 x509CertificateValidator 验证

问题描述

WCF 服务使用具有自签名证书的证书安全性。从谷歌搜索来看,默认验证器似乎应该失败,但服务是正常的。我找不到任何地方设置了certificateValidationMode 来更改此默认行为,或识别任何其他会更改它的东西,所以我很困惑。

我已将 WCF 服务配置为使用自定义 x509CertificateValidator 来验证证书。但是没有调用 Validate() 方法。我的问题是 - 为什么没有调用 Validate 方法?

我之前没有为 WCF 服务配置证书安全性,所以我可能遗漏了一些明显的东西。我怀疑问题出在代码中的其他地方,但我不知道还要寻找什么。

这是我设置自定义验证器的地方:

    viewerHost = new ServiceHost(typeof(ViewerService));

    viewerHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;
    viewerHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator = new CertValidator();

    viewerHost.AddServiceEndpoint(
        typeof(IViewerService),
        getBinding(true, true),
        @"net.tcp://localhost:8746/Viewer/");
    setCertificate(viewerHost);
    addThrottlingBehaviour(viewerHost);
    viewerHost.Open();

以下是上述摘录中 getBinding() 的代码,试图将凭证类型设置为注释掉(它完全停止了连接,而没有调用 Validate() 方法):

private static CustomBinding getBinding(bool useCompression, bool useSSL)
{
    BindingElementCollection elements = new BindingElementCollection();

/* I tried the following after reading CodeCaster's comment, which did not work:             
    SecurityBindingElement security = 
  SecurityBindingElement.CreateCertificateOverTransportBindingElement();*/

    // MessageEncoding
    BinaryMessageEncodingBindingElement binaryMessageEncodingBE = new BinaryMessageEncodingBindingElement();
    if (useCompression)
    {
        GZipMessageEncodingBindingElement gZipMessageEncodingBE = new GZipMessageEncodingBindingElement(binaryMessageEncodingBE);
        elements.Add(gZipMessageEncodingBE);
    }
    else
    {
        elements.Add(binaryMessageEncodingBE);
    }

    if (useSSL)
    {
        SslStreamSecurityBindingElement sslStreamSecurityBE = new SslStreamSecurityBindingElement();
        sslStreamSecurityBE.SslProtocols = SslProtocols.Tls11;    // Currently MD5 certs are in use. This will be changed when they are replaced with SHA256 ones.
        elements.Add(sslStreamSecurityBE);
    }

    // TcpTransportBindingElement
    TcpTransportBindingElement tcpTransportBE = new TcpTransportBindingElement();
    tcpTransportBE.MaxReceivedMessageSize = 1048576;
    tcpTransportBE.ListenBacklog = 1000;
    tcpTransportBE.MaxPendingConnections = 1000;
    tcpTransportBE.MaxPendingAccepts = 1000;
    tcpTransportBE.ConnectionPoolSettings.MaxOutboundConnectionsPerEndpoint = 1000;
    elements.Add(tcpTransportBE);

    CustomBinding binding = new CustomBinding(elements);

    BindingContext context = new BindingContext(binding, new BindingParameterCollection());
    XmlDictionaryReaderQuotas quotas = binaryMessageEncodingBE.GetProperty<XmlDictionaryReaderQuotas>(context);
    quotas.MaxArrayLength = 1048576;
    quotas.MaxStringContentLength = 1048576;



    return binding;
}

setCertificate() 实现:

/// <summary>
/// Sets a server certificate for a service host
/// </summary>
/// <param name="serviceHost"></param>
private static void setCertificate(ServiceHost serviceHost)
{
    // A certificate has to be installed on the server. This certificate is used for SSL encryption
    serviceHost.Credentials.ServiceCertificate.SetCertificate(
        System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser,
        System.Security.Cryptography.X509Certificates.StoreName.My,
        System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName,
        "localhost");
    var test = serviceHost.Credentials.ServiceCertificate.Certificate;
}

标签: c#.netwcfclient-certificates

解决方案


推荐阅读