1

是否有一种简单的方法可以将自定义 X509 证书验证与 BasicHttpBinding(或 CustomHttpBinding 用于同一问题,这将实现仅传输安全性)联系起来?

EDIT1:我在代码中添加了一个 ServerCertificateValidationCallback 以显示它也不会启动

这是我正在尝试做的事情:

1)编写自定义 X509CertificateValidator:

public class MyX509Validator : X509CertificateValidator
{
    public override void Validate(X509Certificate2 certificate)
    {
        Console.WriteLine("Incoming validation: subj={0}, thumb={1}",
                certificate.Subject, certificate.Thumbprint);
    }
}

2)创建主机:

var soapBinding = new BasicHttpBinding() { Namespace = "http://test.com" };
soapBinding.Security.Mode = BasicHttpSecurityMode.Transport;
soapBinding.Security.Transport.ClientCredentialType =
            HttpClientCredentialType.Certificate;

var sh = new ServiceHost(typeof(Service1), uri);
sh.AddServiceEndpoint(typeof(IService1), soapBinding, "");
sh.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine,
           StoreName.My, X509FindType.FindBySubjectName, "localhost");
sh.Credentials.ClientCertificate.Authentication.CertificateValidationMode =
           System.ServiceModel.Security.X509CertificateValidationMode.Custom;
sh.Credentials.ClientCertificate.Authentication.CustomCertificateValidator = 
           new MyX509Validator();
System.Net.ServicePointManager.ServerCertificateValidationCallback += 
           delegate(object sender, X509Certificate certificate, 
                    X509Chain chain, SslPolicyErrors sslPolicyErrors)
           {
                Console.WriteLine("Incoming validation: subj={0}, thumb={1}",
                    certificate.Subject, certificate.GetIssuerName());
                return true;
           };
sh.Open();

3)创建WCF客户端:

var binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var cli = new ServiceReference2.Service1Client(binding, 
           new EndpointAddress("https://localhost:801/Service1"));
cli.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, 
           StoreName.My, X509FindType.FindBySubjectName, "localhost");
cli.HelloWorld();

身份验证工作正常,但MyX509Validator.Validate()永远不会被调用。我怀疑X509CertificateValidator这只适用于消息安全,而不适用于传输。那正确吗?我可以做些什么来覆盖传输级证书验证吗?

4

2 回答 2

1

我假设您正在谈论与 HTTPS 相关的证书...

如果是这样,答案如下: X509CertificateValidationMode 用于您正在交换以提供身份验证的文档的标题中。它对底层传输本身没有任何作用,在本例中是 HTTPS 及其关联的 x.509 证书。所以,你的假设是正确的。

如果要提供传输的自定义证书验证,请System.Net.ServicePointManager.ServerCertificateValidationCallback改用。不过要小心,这是一个应用程序范围的设置。如果您在多个端点之间循环并且不将其设置为 null,它将保持活动状态。

于 2009-04-13T06:46:46.977 回答
0

我正在使用以下设置执行此操作,并且我的自定义验证器肯定会受到影响:

serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode =
    X509CertificateValidationMode.Custom;

serviceHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator =
    new CertificateValidator(ConfigurationManager.AppSettings["Cerficate"]);

我的行为是:

    <behavior name="CustomCertificateBehavior">
      <serviceCredentials>
        <clientCertificate>
          <authentication certificateValidationMode="Custom" />
        </clientCertificate>
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>

我的绑定:

  <basicHttpBinding>
    <binding name="SecureBinding" maxReceivedMessageSize="5242880">
      <security mode="Transport">
        <transport clientCredentialType="Certificate"></transport>
      </security>
    </binding>
  </basicHttpBinding>
于 2012-10-04T14:35:10.830 回答