从WCF创建的ws-security标头中删除timestamp元素

时间:2014-07-08 15:34:23

标签: c# soap ws-security

我正在使用WCF中的旧Java Web服务,该服务需要以下表单中的请求:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header>
        <wsse:Security mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss- wssecurity-secext-1.0.xsd">
            <wsse:UsernameToken wsu:Id="xxx" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-ssecurity-utility-1.0.xsd">
                <wsse:Username>username</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
    </s:Header>
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        ...
    </s:Body>
</s:Envelope>

使用以下配置hack&#34;工作&#34;但我不想在config:

中公开用户名和密码
<binding name="bindingName">
      <security mode="Transport">
        <transport clientCredentialType="Certificate" />
      </security>
</binding>
...
<endpoint address="https://endpoint address"
      binding="basicHttpBinding" bindingConfiguration="bindingName"
      contract="contract"
      name="bindingName">

    <headers>
        <wsse:Security mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss- wssecurity-secext-1.0.xsd">
            <wsse:UsernameToken wsu:Id="UsernameToken-8293453" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-ssecurity-utility-1.0.xsd">
                <wsse:Username>username</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
    </headers>
</endpoint>

我想要使用的是:

<binding name="bindingName">
    <security mode="TransportWithMessageCredential">
        <transport clientCredentialType="Certificate" />
        <message clientCredentialType="UserName" />
    </security>
</binding>

但是这会在安全元素中生成timestamp元素,java webservice会将其生成。

我需要做的是从它生成的XML中删除时间戳,或者为我做一些自定义绑定。

我尝试创建自定义凭据,但这只更改了usernameToken元素。

我已经看过许多很多SO问题(许多来自2007年及之前的问题),其中包括以下内容并没有带来欢乐:

删除时间戳元素的最佳,最简单和最优雅的方法是什么。

提前致谢

1 个答案:

答案 0 :(得分:2)

Kristian Kristensen's blog post about his woes in integrating to a Java AXIS 1.X and WSS4J web service.找到答案。比我之前尝试的黑客更简单,更容易。

您可以使用App.config中的简单自定义绑定解决此问题:

BUGFIX - 以前版本中存在错误 - 忘记在httpTransport中添加证书

<system.serviceModel>
    <bindings>
        <customBinding>
            <binding name="CustomBindingName">
                <security authenticationMode="UserNameOverTransport" includeTimestamp="false">
                    <secureConversationBootstrap />
                </security>
                <textMessageEncoding messageVersion="Soap11" />
                <httpsTransport useDefaultWebProxy="false" requireClientCertificate="true" />
            </binding>
        </customBinding>
    </bindings>

    <client>
        <endpoint address="<endpoint address>" 
            binding="customBinding"
            bindingConfiguration="CustomBindingName"
            contract="<contract goes here>"
            name="EndpointName" />

    </client>
</system.serviceModel>

这提供了正确的SOAP ws-security标头,没有时间戳,只是通过调用此代码来混淆Java服务器

var client = new [clientType]();

client.ClientCredentials.ClientCertificate.Certificate = [certificate];

client.ClientCredentials.UserName.UserName = [UserName];
client.ClientCredentials.UserName.Password = [Password];

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

// TODO wrap in try catch
client.Open();

var result = client.[action](new [RequestType] { ... });

进一步阅读: