5

编辑:

我最终确定 IClientMessageInspector 似乎没有反映消息签名,所以当我实际上在我的请求中获得签名时,我并不知道。所以现在我的新问题,真正的问题......

如何配置 WCF 客户端以提供 SSL 客户端证书并签署 SOAP 标头?

var myBinding = new BasicHttpBinding();
myBinding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;

这将导致标头具有已签名的时间戳。但是,不再提供客户端证书,并且我没有通过 SSL。如果我将第二行更改为:

myBinding.Security.Mode = BasicHttpSecurityMode.Transport;

然后我通过了 SSL,但我的 SOAP 标头不再具有签名块。

有什么办法可以让我获得 HttpWebRequest 以便我可以像这样手动附加 SSL 客户端证书?

webRequest.ClientCertificates.Add(certLoader.Load(@"c:\somecert.pfx"));

原始问题

我正在开发一个 WCF 客户端,该客户端需要与第三方提供的服务互操作,该第三方使用 Forum Sentry 网络设备来保护访问。它们需要 SSL 和传输级别的客户端证书,以及 o:Security 元素,其签名使用标头中的证书。我可以通过标准绑定实现其中一个或另一个,但我似乎无法同时实现两者。理想情况下,他们希望使用与 SSL 客户端证书不同的证书对消息进行签名,但他们说我们可以使用相同的证书进行 SSL 客户端身份验证和对消息进行签名。

在这一点上,我愿意做任何事情来完成这项工作,包括在必要时使用 CustomBinding。

我可以使用以下命令使 SSL 部分正常工作:

var myBinding = new BasicHttpBinding();
myBinding.Security.Mode = BasicHttpSecurityMode.Transport;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var url = "https://blah.com/services/somservice";
EndpointAddress ea = new EndpointAddress(url);
var client = new SoapClient(myBinding, ea);
var certLoader = new CertificateLoader("password");
client.ClientCredentials.ClientCertificate.Certificate = certLoader.Load(@"c:\somecert.pfx");
var resp = client.somemethod(ref profile, new RequestType { version = RequestTypeVersion.Item100 });
4

3 回答 3

2

请发布一个样品工作肥皂(例如供应商提供的一个)。顺便说一句,有比使用自定义绑定更剧烈的动作:)

编辑:要同时使用传输和消息安全性,您需要自定义绑定。谷歌的“wcf 绑定转换器”会自动执行此操作。在自定义绑定而不是 http 元素中将其更改为 https 并使用属性 requirevlientcertificate。对不起拼写我在手机上

编辑:

var c = new CustomBinding();            
MessageSecurityVersion version = MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
var sec = SecurityBindingElement.CreateCertificateOverTransportBindingElement(version);
c.Elements.Add(sec);
c.Element.Add(new TextMessageEncodingBindingElement() { MessageVersion = MessageVersion.Soap11 };)
c.Elements.Add(new HttpsTransportBindingElement() { RequireClientCertificate = true });
于 2012-05-21T17:41:03.073 回答
0

这很丑陋,但可以完成工作。如果您在调试器中查看这些自定义绑定中的每一个的元素,您会发现即使它们的堆栈底部都有一个 HttpsTransportBindingElement,TransportWithMessageCredential 实例也会将 RequireClientCertificate 设置为 false 和几个其他私有成员与设置为假的证书有关。Transport 实例会将这些成员设置为 true。这显然是 WCF,IMO 中的错误。

下面的代码从 customTransportSecurityBinding 中获取“好”的 HttpsTransportBindingElement,并替换 customMessageCredentialBinding 中的“坏”元素。然后,您将修改后的 customMessageCredentialBinding 传递给您的客户端构造函数。

    var transportSecurityBinding = new BasicHttpBinding();
    transportSecurityBinding.Security.Mode = BasicHttpSecurityMode.Transport;
    transportSecurityBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
    transportSecurityBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;
    var customTransportSecurityBinding = new CustomBinding(transportSecurityBinding);

    var messageCredentialBinding = new BasicHttpBinding();
    messageCredentialBinding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential;
    messageCredentialBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
    messageCredentialBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;
    var customMessageCredentialBinding = new CustomBinding(messageCredentialBinding);

    // replace transport binding element from message credential binding with the transportSecurityBinding transport binding
    // which will include the cert for SSL mutual auth.
    customTransportSecurityBinding.Elements[customTransportSecurityBinding.Elements.Count - 1] = customMessageCredentialBinding.Elements[customMessageCredentialBinding.Elements.Count - 1];

var client = new SomeSoapClient(customTransportSecurityBinding, ea);
于 2012-05-22T13:55:54.617 回答
0

如果有人为上述答案寻找 app.config 版本的自定义绑定:

<bindings>
      <customBinding>
        <binding name="SignedMessageBinding">
          <security messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" /> 
          <textMessageEncoding messageVersion="Soap11" />
          <httpsTransport requireClientCertificate="true"  />
        </binding>
      </customBinding>
</bindings>
于 2017-10-10T11:45:38.940 回答