Remove timestamp element from ws-security headers created by WCF

c#, soap, ws-security

Solution

Found the answer on Kristian Kristensen's blog post about his woes in integrating to a Java AXIS 1.X and WSS4J web service.. So much simpler and easier than the hacks I was trying previously.

You can solve this with a simple custom binding in App.config as so:

BUGFIX - there is a bug in previous version - forgot to add certificate in 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>

This gives the correct SOAP ws-security header without the timestamp that confused the java server just by calling this code

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] { ... });

Further Reading:

- Source of links to answer - Kjell-Sverre Jerijærvi's blog

- Where I found the actual answer - Kristian Kristensen's blog

Problem

I am consuming an old Java web service from WCF that requires the request in the form: ``` <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> ``` Using the following config hack "works" but I don't want the username and password exposed in 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> ``` What I want to use is something along the lines of: ``` <binding name="bindingName"> <security mode="TransportWithMessageCredential"> <transport clientCredentialType="Certificate" /> <message clientCredentialType="UserName" /> </security> </binding> ``` But this generates the `timestamp` element in the security element, which the java webservice borks on. What I need to do is remove the timestamp from the XML it generates or have some sort of custom binding to do it for me. I tried creating custom credentials, but this only changed the `usernameToken` element. I have already looked at many, many SO questions (many from 2007 and earlier) including the following with no joy: - Remove Timestamp element from Security - How to make WCF Client conform to specific WS-Security What is the best, simplest and most elegant way to remove the timestamp element. Thanks in advance

Original source

Related problems