Udostępnij za pośrednictwem


WCF – BEA Aqualogic Interop Issue

There are always constraints when it comes to interoperability between .NET and Java platforms. I had to go through a 3 week long struggle in making a simple thing work on these platforms.

Here is the requirement,

Develop a WCF client which should talk to a Java Web Service running on Aqua Logic Web Server. The service is secured by 2 Way HTTPS (both Server & Client Certs) and message signing for non-repudiation.

Immediately after you see this requirement, anyone would just advice “TransportWithMessageCredentail” security mode which is out of the box as I did. I precisely did the same but wouldn’t succeed. Why?

The reason is simple. “TransportWithMessageCredential” by default signs the “timestamp” element on the SOAP Header and sends it across. It is designed in this way because, the timestamp is the smallest attribute and signing it takes lesser cycles of canonicalization, compared to any other element in the entire SOAP content. But, ALSB (AquaLogic Service Bus) wouldn’t recognize this request. It was always throwing an error saying,

No id attribute on element http://schemas.xmlsoap.org/soap/envelope/:Body

This means that ALSB requires the Body to be signed, and nothing else.

There is no way to address this interop issue with not only the out-of-box “TransportWithMessageCredentail” security mode but also with any other custom configuration as well.

But there is always a way to make things work in some or the other way. Here I show you how to make it work with a small modification on the service side.

In my above said requirement, the Request is signed (SOAP Body), but not the Response. With the following configuration, you can make WCF sign the request (body) and still use transport security.

<customBinding>
<binding name="SigningBinding">
<textMessageEncoding messageVersion="Soap11" />
<security authenticationMode="MutualCertificate" requireDerivedKeys="false"
includeTimestamp="false" keyEntropyMode="ClientEntropy"
messageProtectionOrder="SignBeforeEncrypt"
messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversation

February2005WSSecurityPolicy11BasicSecurityProfile10"
requireSecurityContextCancellation="false" securityHeaderLayout="Strict" allowSerializedSigningTokenOnReply="true">
<secureConversationBootstrap />
<localClientSettings detectReplays="false"/>
</security>
<httpsTransport requireClientCertificate="true"/>
</binding>
</customBinding>

But the catch here is, WCF expects the response also to be signed as it signs the request. It necessarily asks you to have the server certificate as well, installed on the client machine which is accessing the service.

If you have the freedom to make the service behave so, you are out of trouble.

Below is the rest of the configuration..

<endpoint address=https://domain.com/services/service
               behaviorConfiguration="ServiceSecurityBehavior" binding="customBinding"
bindingConfiguration="SigningBinding" contract="MyContract"
name="SuscribeEventEndPoint">
<identity>
<certificateReference storeLocation="LocalMachine" x509FindType="FindByThumbprint"
findValue="v2d43d464abd384b5cc3a2d669862807241234567" />
</identity>
</endpoint>

<behaviors>
<endpointBehaviors>
<behavior name="ServiceSecurityBehavior">
<clientCredentials>
<clientCertificate findValue="123459f47cb80f67tgb385ae0ebc0b92f8861234"
storeLocation="LocalMachine" x509FindType="FindByThumbprint"/>
<serviceCertificate>
<defaultCertificate findValue="v2d43d464abd384b5cc3a2d669862807241234567"
storeLocation="LocalMachine" x509FindType="FindByThumbprint"/>

              </serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>

Comments

  • Anonymous
    October 07, 2008
    The comment has been removed

  • Anonymous
    October 07, 2008
    Hi Imaya, I am a java developer and i have never had any chance to work in this way..It is very interesting and informative ...I Got to know many things...Good..I appreciate your interest and dedication towards this work...Keep it up...

  • Anonymous
    January 22, 2009
    Hi Imaya, Nice article! I'm writing a WCF client that consumes a Java Web Service, but I'm not able to change it. Does that mean that I can't work around this error?

  • Anonymous
    January 22, 2009
    Kristof, If you are facing the same problem then you are in trouble. You can never make it work, unless you tweak it to the core by using reflection. I have a solution for this, but that is not supported by Microsoft. Please try to change the Java Web Service's behavior. That is better for future support and maintenance.

  • Anonymous
    May 26, 2009
    Hello Imaya, You mention a tweak using reflection; could you say a little bit more about this? Thanks in advance!