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