WCF每个连接服务器证书验证

Blu*_*Fox 9 c# ssl wcf

我试图绕过https证书验证只到我们自己的测试环境(多台机器),同时试图保持所有其他连接的证书验证.

从在线阅读,大多数(如果不是全部)WCF相关的建议似乎指向类似的以下内容

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Run Code Online (Sandbox Code Playgroud)

但是,这是一个全局设置,我想仅将其应用于特定连接.这甚至是可能/支持的使用场景吗?

tbo*_*lon 9

在使用.net 4.5时,我终于找到了真正的解决方案.

此代码允许您仅为特定WCF客户端使用自定义验证程序.

它已针对BasicHttpBinding进行了测试BasicHttpSecurityMode.Transport.

有一个名为新属性SslCertificateAuthenticationClientBase.ClientCredentials.ServiceCertificate.

您可以使用X509ServiceCertificateAuthentication可以提供自定义的位置初始化此属性X509CertificateValidator.

例如:

// initialize the ssl certificate authentication
client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication()
{
   CertificateValidationMode = X509CertificateValidationMode.Custom,
   CustomCertificateValidator = new CustomValidator(serverCert)
};

// simple custom validator, only valid against a specific thumbprint
class CustomValidator : X509CertificateValidator
{
    private readonly X509Certificate2 knownCertificate;

    public CustomValidator(X509Certificate2 knownCertificate)
    {
        this.knownCertificate = knownCertificate;
    }

    public override void Validate(X509Certificate2 certificate)
    {
        if (this.knownCertificate.Thumbprint != certificate.Thumbprint)
        {
            throw new SecurityTokenValidationException("Unknown certificate");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


The*_*man 2

像这样的东西:

ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(ValidateCert);

public static bool ValidateCert(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    string requestHost;

    if(sender is string)
    {
        requestHost = sender.ToString();
    }
    else
    {
        HttpWebRequest request = sender as HttpWebRequest;

        if(request != null)
        {
            requestHost = request.Host;
        }
    }

    if(!string.IsNullOrEmpty(requestHost) && requestHost == "my_test_machine")
        return true;

    return sslPolicyErrors == SslPolicyErrors.None;
}
Run Code Online (Sandbox Code Playgroud)

请注意有关参数的文档sender

传递给 RemoteCertificateValidationCallback 的 sender 参数可以是主机字符串名称或从 WebRequest 派生的对象(例如 HttpWebRequest),具体取决于 CertificatePolicy 属性

免责声明 - 我没有对此进行测试,我是根据文档编写的。YMMV。