.NET Zone is brought to you in partnership with:

Yaron is a Microsoft MVP in the Connected System Developer realm. Yaron authors the successful Web Services 2.0 blog, in which he helps the community with some of his favorite topics: Web services, security and interoperability. Yaron is also an architect in HP. Yaron is a DZone MVB and is not an employee of DZone and has posted 27 posts at DZone. You can read more from them at their website. View Full User Profile

When EnableUnsecuredRespose Requires an Unsecured Response

04.26.2012
| 3302 views |
  • submit to reddit
A few weeks ago I had to call a legacy wse2 service from a Wcf client. The service behavior was:

  • Request must be encrypted and signed at the message level
  • Request must contain a timestamp inside the security header
  • Response is neither encrypted nor signed
  • Response nevertheless contains a timestamp inside a security header

  • You might think that dismissing the signature requirement from the response would do good for interoperability - after all this is less work. However this time less was more. Turns out that Wcf loves symmetry and does not encourage messages in one direction to be signed and in the other direction to be clear. But hey! This complaint is so WCF 3.5. In 4.0 we got the goodie of EnableUnsecuredResponse:
    <security authenticationMode="UserNameOverTransport"
              enableUnsecuredResponse="true"
              includeTimestamp="false">

    When this setting is on Wcf should be ok with an unsigned response. But in my case even with this flag I was still getting this error:

    The security header element ‘timestamp’ with ‘Timestamp-xxxx’ id must be signed.

    As you remember the service returns an unsigned timestamp element. Turns out we have this chain of rules:

    request contains a timestamp and has some signature requirement -->
    the timestamp is always signed (even if we do not wish that) -->
    the response must contain a signed timestamp unless EnableUnsecuredRespose in on. In that case timestamp is optional, but if present it must be signed.

    So I had to find a way to remove the timestmap from the response. Since the service could not be changed I used my good old friend the custom encoder.

    But even after that I got this error:

    The 'body', 'http://schemas.xmlsoap.org/soap/envelope/', required message part was not signed.


    So WCF was still looking for some ws-security goodies. To solve this I had to remove the security element all together from the response. Here is the snippet I added to the encoder:
    if (n.MoveToFollowing("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"))
    {
        n.DeleteSelf();
    }

    Many times removing the security element at all exposes us to some risks like replay attacks or a man in the middle. However here we knew up front that the service does not use any interesting security features in the response so there was no regression.

    Conclusion
    EnableUnsecuredRespose will allow us not to have a security element in the response even if the request has it. But if the response contains a security element nevertheless, then wcf will take it seriously and if it does not comply with the expected requirements the interaction will fail. 

    Published at DZone with permission of Yaron Naveh, author and DZone MVB. (source)

    (Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)