Saturday, May 5, 2012

How to fix Wcf cache of dynamic Wsdls

@YaronNaveh

One of the least used Wcf extension points is IWsdlExportExtension. This extension allows to customize the wsdl document which Wcf emits. Since you rarely want to do that, this extension is not commonly used. When it is already used it is usually in the context of flattening the wsdl. A different use case I have recently seen is to push dynamic content into the wsdl. More specifically a user was trying to generate xsd schemas from a live database table and to put it to the wsdl so clients would always get the latest schema. The Wcf service itself was treating the request as Xml anyway so it did not care for such changes. The requirement was for the wsdl to reflect the latest db changes at any time. Our problem was that once the wsdl was generated for the first time it would not be regenerated. This resulted in a stale schema.

This is how we created the wsdl exporter:


When we run this service and open the wsdl we get this:


When we refresh the wsdl after a few seconds we still get this:


This is not a browser or proxy cache. Wcf does not recreate the wsdl - which can also be seen by putting a breakpoint (which is only called once) on the exporter.

This behavior makes since when you consider the case where there is no importer extension - then the wsdl is generated based on the data contract assembly, and as long as that assembly does not change the wsdl will not also. However we have chose to put dynamic logic in ExportEndpoint method so that default behavior did not work well for us.

One way to fix that is to use a message inspector to update the wsdl before it is sent to the client. In this case IWsdlExportExtension is not required at all. This approach is described here.
An alternative could be to build a Wcf rest endpoint in the same service to act as a proxy to the real wsdl.

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Tweets of the week: It's DevOps Borat

@YaronNaveh

Borat likes DevOps:



Soap / Rest / Wsdl still a hot topic:





@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Friday, April 27, 2012

Tweets of the week: A Wcf love/hate thing

@YaronNaveh

Since I opened my twitter account I've seen a few witty fights insights on web services, so here I share them. If you stumble upon anything worth to get into my next list let me know.

Soap vs. Rest reloaded?




Wcf love/hate thing:




Asp.Net Web API to the rescue:



Wsdl confessions:




If you see anything worth to put in my next list let me know.

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Declaratively ignoring must understand headers

@YaronNaveh

A soap header may specify a "must understand" flag. This instructs any processing node to throw an exception if this header is not understood by it. Such a behavior is sometimes useful and sometimes very annoying, depending on the circumstances. Let's see how such header looks like in soap:


By default a Wcf service will validate all incoming mustUnderstand headers a client sends. If it does not understand them it will throw the famous 'Did not understand "MustUnderstand" header' exception. Typically you would instruct Wcf not to validate these headers like this:


But this kind of "hard codes" this behavior to the service. Wouldn't it be nice to decide at the configuration level if we want such a behavior or not?

All we need to do is define this class:


Then in the config register it:


And we can now configure our endpoint(s) with this behavior:

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Wednesday, April 25, 2012

When EnableUnsecuredRespose *requires* an unsecured response

@YaronNaveh

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:


    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:


    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.

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!

    Saturday, April 21, 2012

    Ws.js - A ws-* implementation for node.js

    @YaronNaveh

    (Get Ws.js on github)

    Some time ago I introduced Wcf.js - a wcf-inspired client soap stack for node.js. However Wcf.js itself is a small wrapper on top of Ws.js - the ws-* implementation for node.js. You got it right: Your node.js apps can now access your core services using various ws-* standards. No more proxies for "protocol bridging", no more service rewrites.

    Get it here.

    Here is a quick sample on what we can do with Ws.js:


    The above example adds a username token to the soap. The output soap will be:


    For detailed usage instructions check it out on github.

    Ws.js currently supports:

  • MTOM
  • WS-Security (username tokens only)
  • WS-Addressing (all versions)
  • HTTP(S)

  • Coming up next is probably deeper ws-security support including x.509 certificates encryption and signature. Needless to say that any capability added to ws.js will also apply to wcf.js.

    Here is the project page on github.

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!

    Sunday, April 15, 2012

    I'm on Twitter: @YaronNaveh

    @YaronNaveh

    I just started my twitter account - @YaronNaveh (yeah I'm a late bloomer). I'l be mostly writing about the stuff I love (node.js, wcf, web services) but expect some new stuff too! See you there.

    @YaronNaveh

    What's next? get this blog rss updates or register for mail updates!