This means that your WCF service uses X.509 certificates negotiation. In such a scenario, clients use the server X.509 certificate for encryption. The unique here is that clients are not required to have this certificate out of band (as in most cases), rather they get this certificate using a SOAP-level negotiation. This is implemented as an extension over WS-Trust. While this is not strictly a proprietary Microsoft solution, Microsoft was the only one to implement it so far. In short - X.509 negotiation (SslContextToken) is not interoperable. Unfortunately(?) the default configuration of a WCF service is to use this negotiation. To turn it off either update your WsHttpBinding configuration:

Monday, October 27, 2008

If you are writing a JAX-WS web service then you must be familiar with the Java.Net support forums. If you are a WCF developer you have surely bookmarked the MSDN forums. But what if you are an Axis2 developer seeking for interoperability with WCF? Or a .Net 2.0 tester having trouble with an XFire service? This post will give you a hint on where to ask your questions.

Axis2 / RampartIf you need to work with an Axis2 service you can try to check if there is a bug already open on your case in the issues tracker:

There are various ways to get this SKI from a certificate. Some of them are:

The certificate might contain an out-of-band generated SKI inside it as an "extension".

An SHA1 thumbprint is calculated out of the certificate raw data.

The certificate serial number and issuer name are used

The certificate subject name is used

The SKI needs to be calculated from the certificate using some algorithm

Guess which option causes us most trouble? Right, the last one. The problem is that it is not concrete enough. There were a few ways to generate this SKI and so there were misunderstandings between Java and Microsoft applications and even between different versions of the same frameworks.

Let's take a sample certificate as an example. First convince yourself that it does not contain SKI extension:

Now look at the format WebSphere 6 server would expect:

M9WWSXczVFt2otJ3adPjfmbUxU8=

WSE2 would generate:

bBwPfItvKp3b6TNDq+14qs58VJQ=

And WSE 3 generates this one:

SdPjfmbUxU8=

With WCF you would get the following exception:

System.NotSupportedException:

"'X509SecurityToken' does not support 'X509SubjectKeyIdentifierClause' creation."

As WCF does not work with certificates that do not have SKI when the latter is explicitly required - and that's what I did for this sample.

So by all and all we've got 4 different SKI's out of one certificate!

Out of these 4 frameworks there is a way to interoperate using SKI and X.509 that does not contain SKI extension between the following:

Note: It is possible to interoperate between these platform in various other ways. If you now design your system you should use these ways. The information here is provided for those who are already working with a given systems.

So how can we reach this interoperability?

To interoperate with WebSphere all you need to do is to change WSE2 configuration to:

It's been over a day now that the WCF forum in MSDN is down. However for anyone in a need to raise an urgent development issue it looks like forever. It was just upgraded to its new version two week ago and now this. It's also strange that all other MSDN forums that were upgraded to the new version are up. I'm not suggesting there's a conspiracy of any sort but it's still strange. Why couldn't it be the WPF Forum or even Windows Live Controls Development Forum?

Tuesday, October 21, 2008

WCF logging is a very important debug feature in .Net 3.5. However you shouldn't always trust what you see...

Removing nonce and passwordsThe first case where the logging may mislead is when security mechanisms such as username, password or nonce are used. For security reasons the log will no show them (see image bellow)

No WS-AddressingThe WS-Addressing standard is used in some of the bindings. When it is not used (as in basicHttpBinding or certain customBinding) the log will still show you something like:

Thursday, October 16, 2008

WSE is the previous generation of Microsoft WS-* stack. For this reasons a lot of Microsoft shops are in a need to interop between WSE & WCF. I'm not going to invent the wheel here - there's a great article in MSDN on this.

There is one delicate point I'd like to emphasize. WCF supports WS-Policy which is a way for a service to specify what WS-* requirements it has (e.g. security, attachments). The policy is contained inside the wsdl:

When a WCF client is generated using "Add service reference" the app.config is automatically synchronized with the WS-Policy from the service wsdl.

WSE does not support this usage of WS-Policy in any of its versions. So when a wsdl that was created using WSE is imported using WCF the app.config needs to be updated manually (or via the config editor). One exception is SSL which WCF can identify from the service url.

For a WSE WSDL, WCF generats a basicHttpBinding by default. In most cases a customBinding would be required in order to reach interoperability on the wire using rich security options, soap12 and MTOM.

I recently saw an error that a WSE server returned for a WCF client:

Header http://schemas.xmlsoap.org/ws/2004/08/addressing:Action for ultimate recipient is required but not present in the message.

A short investigation showed that the WCF client used the auto-generated app.config with its basicHttpBinding. That's why it did't send any WS-Addressing headers as the error indicates. The solution is of course to manually edit app.config and move to an appropriate customBinding.

Wednesday, October 15, 2008

Every wsdl has a "style" and an "encoding". They only set the soap message format on-the-wire so they do not matter for the most developers most of the time. However it is highly recommended to always use style=document and encoding=literal to increase interoperability. For example:

There is a special recommended style to write doc/lit wsdls: doc/lit/wrapped. In this format each message is named with the operation name suffixed by "request" or "response". The message contains only one part named "parameters" (this name never appears in the soap in doc/lit so it shouldn't matter). There are other requirements - see more details at Anne's blog. For example (pseudo wsdl):

There are a few advantages to doc/lit/wrapped among them a cleaner model and a more expressive soap message. However this style raises a few interoperability issues:

Axis2 code generationIf you've read Anne's explanation you know that the root element in the message is redundant (since it always has to be used anyway) and so the generated stub looks more complex than it should. Keith explains how to solve this.

WCF DataContractSerializerWCF has a few flavours of serializers. DataContractSerializer is the recommended one. However this serializer can only be used in doc/lit/wrapped. So If your use svcutil to generate a proxy like this:

You will get this error if your wsdl does not comply to doc/lit/wrapped in one or more ways. For example if your part names are not "parameters". The way to solve this is either to change the part names to "parameters" (and fix all other issues) or to not force svcutil to use DataContractSerializer:

In this case WCF will downgrade itself to use the .Net 2.0 XmlSerializer. This serializer is not bad at all and was used in .Net 2.0 applications. It does have a less optimal performance than the new serializer but you can use it in production applications if you need. Dan wrote an interesting comparison of the two serializers.

.Net 2.0 derived typesI won't dive into details with this one. Generally speaking .Net 2.0 might try to serialize as doc/lit/wrapped some wsdls which are not really in this format and so it can fail code generation. One example is when the wrapper element has derived types.

This one isn't that cryptic actually but its cause is not always clear:

System.TimeoutException:

The request channel timed out while waiting for a reply after 00:01:00. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout.

There can be various reasons why a proxy would throw such an exception with the main one being that the server is not available. However one other reason is that the maximum number of allowed sessions was reached. Some bindings (e.g. wsHttpBinding) under some configurations (e.g. Security or ReliableMessaging) cause the server to open a session with each unique client that accesses the service. A session is closed after the client explicitly closes the proxy or when the client is inactive for some time. There can only be a limited number of open sessions. When this limit is reached clients get the above timeout exception. In case you want to raise this limit you need to increase the number of allowd sessions

You can see that the difference is in the namespace of the inner "name" element: It is from the "http://someOrganization" namespace in my request but from the empty namespace in the working request. For those of you less familiar with xml namespaces: In the previous request "xmlns" defined a default namespace for all elements without prefixes; In this case only elements that explicitly use the "ns" prefix belong to the namespace.

After a short investigation the cause of this was identified. Let's take a second look at the schema (which is a part of the wsdl file):

Tuesday, October 14, 2008

Today's exception can happen when X.509 certificates negotiation is used. One case when it is used is when you use wsHttpBinding with:

negotiateSerciveCredential="True"messageClientCredentialType=[anything but "Windows"]

But there are other cases as well.

You may get the following exception at the client:

"SOAP security negotiation with 'http://localhost:13037/WCFService54/Service.svc' for target 'http://localhost:13037/WCFService54/Service.svc' failed. See inner exception for more details."

The inner exception shows:

{"The X.509 certificate CN=WSE2QuickStartServer chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.\r\n"}

The reason for that is that the certificate the server uses is not trusted on the client machine. We can see this by double-clicking on the certificate in the file system or in the windows certificate store:

You have 2 ways to solve this:

1. Make sure the service certificate is trusted on the client machine. For example install its issuer certificate in the trusted root store.

OR:

2. This is just for testing and should not go to production. You can disable the server authentication by the client: On the client side create a new endpoint behaviour with a "clientCredentials" behaviour element and set its serviceCertificate/authentication/certificateValidationMode to "None".

Monday, October 13, 2008

Your service WSDL file is the contract between you and your web service clients. Whether you manually write the WSDL or let your framework automatically generate it for you - you want to make sure it is valid (otherwise you'l have no clients!).

There is more than one way to define the validity of a WSDL: Does it need to be valid according the WSDL XML schema? Does it need to comply to known best practices? Does it need to be parsed correctly by common soap stacks? There are different ways to test each of these requirements. Commercial tools, like XMLSpy, can help you with some. Today I'll show you a free alternative: the WSI test tool. WSI is the web services interoperability organization and it has defined the WSDL "basic profile" - a set of best practice recommendations for WSDLs. They have also published a tool that can tell you if your WSDL confirms to this profile and today I'll show you how to use it.

Step 1 - Download the WSI test tool
Go to the downloads page in the WSI site and download "Interoperability Testing Tools 1.1". It has a C# and a Java version - today we will use the C# one but using the Java is similar.

Step 2 - Extract the tool
Just extract the zip to some folder

Step 3 - Configure the test
Copy wsi-test-tools\cs\samples\analyzerConfig.xml to wsi-test-tools\cs\bin and open it with a text editor. Change the following values:

wsdlURI - Should contain the url for your wsdl, for example http://MyServer/MyService.asmx?WSDL

serviceLocation - Should contain the url for your service, for example http://MyServer/MyService.asmx

wsdlElement - This is the most confusing one. Your service has at least one endpoint/port. Here you need to define which one you currently want to test. In order to supply this data open your WSDL in internet explorer and notice that its structure is something like:

So take the value of the "targetNamespace" from here and put its value in the "namespace" attribute of the "wsdlElement" element in the configuration. Also take the value of the "name" element and put it in the "wsdlElement" element value. So the "wsdlElement" configuration may look like:

Saturday, October 11, 2008

So, you want to write an Axis2 web service and have .Net WCF clients too? Or maybe you already have a .Net 2.0 endpoint and want it to be consumed by WSIT? Yes, that’s possible, but there is some important stuff you should know about. Whether you are a .Net WCF, AXIS2, Metro or any other framework developer/tester – you want to stay tuned for this series.

Arun came up with an interesting interoperability issue for WSDL's without SoapAction. SoapAction is an on-the-wire-acronym for web service operations. For example in a web service "Calculator" the operation "Add" can have a SoapAction of "http://myService/Add" (but any arbitrary name can be used). Here is how this appears in the wsdl:

An issue arises when no SoapAction appears: Should we use an empty SoapAction or a default one? Arun explains how this is handled in WSIT (Tango) and WCF. The conclusion is to always explicitly declare a SoapAction for all operations. If your framework generates the WSDL for you - make sure you annotate it correctly so it emit this information.

So, you want to write an Axis2 web service and have .Net WCF clients too? Or maybe you already have a .Net 2.0 endpoint and want it to be consumed by WSIT? Yes, that’s possible, but there is some important stuff you should know about. Whether you are a .Net WCF, AXIS2, Metro or any other framework developer/tester – you want to stay tuned for this series.

This first post deals with XML schema, what you can do with it and – more importantly – what you shouldn’t do with it. I’m not going to preach you on service-first vs. wsdl-first approaches – others wrote some goodpostson it. I am going to recommend you on some good habits no matter which approach you take.

DO be aware of your schemaIf you are a wsdl-first type of developer then the schema is the first item you get to be aware of. But even if you prefer working with annotated classes: Be aware of how the different language types and annotations affect your wsdl – you don’t want to find yourself with a non-interoperable wsdl at a late stage.

DO be aware of schema subsetsThis one is more for Java developers wanting to build service that interoperate with WCF. Microsoft has decided that WCF will support only a subset of the XML schema as a first class member. The main reason is probably to promote simplicity. This subset does NOT include xsd:choice, xsd:attribute and some other very common structures. This is the WCF supported subset – be aware of it!One word of restriction is required: Even if you use unsupported schema constructs in your wsdl WCF proxies have a “backward compatible” mode and they “downgrade” themselves to the .Net 2.0 supported schema subset which is larger. So it’s not the end of the world. However for various reasons, including performance and programming model ease of use – try to stick to the WCF supported subset.

DO ensure schema completenessIf your schema uses some type – you have to define that type in the schema or reference another schema that defines it. In the past there were some issues with types that one framework could understand internally and that’s why it didn’t put them in the wsdl - causing other frameworks to fail. So whenever you use a system type which is not the simple integer/string/etc. you should ensure its definition appears in the wsdl. For example if you are writing a .Net 2.0 web service and one method looks like this:

Of course the same goes for java types such as maps and vectors – make sure they appear in the wsdl.

DO NOT use schema types which are known to be problematicOne example here is xsd:date and xsd:time which are not directly supported by .Net. The .Net framework treats them both as xsd:dateTime so some semantics would get loss.

That’s it for today. Stay tuned for the following posts in this series. If you have any schema related tips feel free to drop a comment.

We continue our journey in WCF error messages. Today’s error is actually somehow related to the first cryptic WCF error message. The use case here again includes X.509 certificates. This time we are just using xml digital signature without encryption. When we run our client we get the following error:

Since we already know how to configure wcf tracing we did just that on the server. Surprisingly enough the trace contained no error! Furthermore, the message logs in the server shows that the server got a valid request and even sent the correct response. Hmmm…The next step is to configure tracing and logging at the client. The logging seems fine and the trace log shows us the same exception “Cannot resolve KeyInfo…”.

What happened is exactly the same as with last time: The client and the server are not using matching X.509 certificates. As suggested there, you should verify the correctness of the X.509 references in web/app.config. If that doesn't help - remove and reinstall the relevant certificates from the windows certificate store.