Question

I have a WCF custom binding that uses the TransportSecurityBindingElement security element, but am having continual issues with the time accuracy on both the client and the (third party) server.

How can I remove the seconds to make timestamp only accurate to the minute (I'm told that the server will accept this).

Alternatives idea's I've had is to update the system time before every request, however this assumes (incorrectly) that the server time is accurate. I've also tried to remove the timestamp altogether (it might not be required), but I get an System.InvalidOperationException saying Signing without primary signature requires timestamp.

.Net Code to build security element:

    Dim msgSecVer As System.ServiceModel.MessageSecurityVersion = ServiceModel.MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10

    Dim tsbe As TransportSecurityBindingElement = SecurityBindingElement.CreateCertificateOverTransportBindingElement(msgSecVer)
    tsbe.EnableUnsecuredResponse = True
    tsbe.SetKeyDerivation(False)
    tsbe.AllowInsecureTransport = True
    tsbe.IncludeTimestamp = True

    'adding clock skew doesn't seem to make any difference?
    Dim clockSkew As TimeSpan = TimeSpan.FromMinutes(1)
    tsbe.LocalClientSettings.MaxClockSkew = clockSkew
    tsbe.LocalServiceSettings.MaxClockSkew = clockSkew

    Return tsbe

Message header, note (possibly excess) accuracy of timestamp:

POST http://wwwqa.xxxx.com/services/
Content-Type: text/xml; charset=utf-8
VsDebuggerCausalityData: xxxx
SOAPAction: ""
Host: wwwqa.xxxx.com
Content-Length: 2400
Expect: 100-continue
Connection: Keep-Alive

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <s:Header>
        <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <u:Timestamp u:Id="_0">
                <u:Created>2013-12-04T10:53:13.568Z</u:Created>
                <u:Expires>2013-12-04T10:58:13.568Z</u:Expires>
            </u:Timestamp>
            <o:BinarySecurityToken u:Id="uuid-bc441202-xxxx-xxxx-a176-02f2a61a6002-1" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">....xxxx....</o:BinarySecurityToken>
            <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
                <SignedInfo>
                    <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                    <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                    <Reference URI="#_0">
                        <Transforms>
                            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <DigestValue>xxxx</DigestValue>
                    </Reference>
                </SignedInfo>
                <SignatureValue>xxxx</SignatureValue>
                <KeyInfo>
                    <o:SecurityTokenReference><o:Reference URI="#uuid-bc441202-xxxx-xxxx-a176-02f2a61a6002-1"/></o:SecurityTokenReference>
                </KeyInfo>
            </Signature>
        </o:Security>
    </s:Header>

No correct solution

OTHER TIPS

The only way I see to get it done is to move to a Transport-only security in your client and then add the security header yourself in a custom encoder. Generating the security header includes:

  1. Generating the timestamp and pushing it in to the SOAP (easy).
  2. Generating the signature (hard). See here and the GetSignature commented our method here. Then push it to the SOAP.

To manipulate the SOAP implement the encoder and in the the WriteMessage method where you have access to the message load it to XmlDocument and manipulate it (e.g. add the headers).

If you're running your WCF host with IIS, you could add a custom-written Module - a .NET DLL - that intercepts the message in IIS, reads, parses and removes the seconds, then passes the message on to your WCF service.

As I recall, the module program picks up and reads the HTTPContext, allowing you to alter the message any way you like, even adding entirely new fields to the header and body sections.

But this approach only works if you're using IIS to front or manage your web service.

Here's a link to it: http://www.iis.net/learn/get-started/introduction-to-iis/iis-modules-overview#Querying

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top