Wednesday, January 6, 2010

Axis2 & Wcf Interoperability

@YaronNaveh

Recently I had to consume an Axis2 web service using a Wcf client. Axis2 used the rampart module for message security where a mutual X.509 certificate was required. Since I had control over both client and server I was able to fine tune them to reach perfect interoperability.

On the Axis side, I have found the WS-Policy flavor configuration better to work with (interoperability-wise) .

This is the Axis configuration:



and this is the Wcf configuration:



Here is the full Axis2 service (which is based on the rampart SDK sample):



and the wcf client:



You will also need certificates.

Client certificate:



Server Certificate:



If prompt for a password use "adminamdin".

This is the Java key store:



and the password is "adminadmin".

If you want to use your own certificate just make sure the certificates have an SKI.

@YaronNaveh

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

33 comments:

Mohammed Abed said...

what is the java key store for the certificates ?

Yaron Naveh (MVP) said...

Mohammed - great point... I added it to the post.

AdoUra said...

i tried this setup but it generate the following exception : Cannot find a token authenticator for the 'System.IdentityModel.Tokens.X509SecurityToken' token type. Tokens of that type cannot be accepted according to current security settings. : any help?

AdoUra said...

adding allowSerializedSigningTokenOnReply="true" to the Security/CustomBinding it generate the following exception :
" The incoming message was signed with a token which was different from what used to encrypt the body. This was not expected. "

Yaron Naveh (MVP) said...

AdiUra

Did you try to run my code or have you copied & paste the relevant parts? First try to run my code using the same certificates.

AdoUra said...

run it as it is !!

Yaron Naveh (MVP) said...

The same settings work on my machine. Try to setup a WCF client first to see if that works.

Anonymous said...

Thanks Yaron.
Do you have a similar example for WCF Service and a axis2 client using mutual certificate.
Appreciate your help.

Yaron Naveh (MVP) said...

Anonymous

I don't have one available but I would expect rampart mutual cert sample to be compatible with WCF.

Anonymous said...

I have been searching google for many days and checked all samples of axis2. I am not able to find any solution to my requirement. Request you to kindly provide a sample/link/pointer how I can achieve this.

We have an axis2 1.3 client talking to WCF service. Our client send RST/SCT request and service sends back RSTR response back to client with SecurityContextToken.

We need to use this token for signing further request to service to call the actual operation for data (earlier request just being for getting SCT).

How to use SecurityContextToken for further signing and including this in Security tag and KeyInfo tag. Here is the sample XML which I need to generate to send to WCF service

<o:Security s:mustUnderstand="1"
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
...
<c:SecurityContextToken u:Id="uuid-f54bacef-5c6f-44e8-b13f-c79c15106520-49" xmlns:c="http://schemas.xmlsoap.org/ws/2005/02/sc""> <c:Identifier>urn:uuid:7607b3fc-1845-4633-8a76-4131001b058a</c:Identifier>
</c:SecurityContextToken>

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
...
<KeyInfo> <o:SecurityTokenReference> <o:Reference ValueType="http://schemas.xmlsoap.org/ws/2005/02/sc/sct" URI="#uuid-f54bacef-5c6f-44e8-b13f-c79c15106520-49"/></o:SecurityTokenReference>
</KeyInfo>
</Signature> </o:Security>

If you notice here Security header has SecurityContextToken tag and Signature having reference to same token in KeyInfo. How can we achieve this in Axis2

Thanks in advance.

regds
Brijesh

Yaron Naveh (MVP) said...

Generally you do not have to do anything special. You should configure Axis to do it automatically. I don't have a direct example: Try to check in the Axis security module (rampart) SDK as it comes with samples, or ask in Axis2 forum.

AdoUra said...

Hello yaron , i returned to my issue again and i have question : can i configure .net client and axis2 server in such way that .net client send encrypted requests and receive responses plain text ?

Yaron Naveh (MVP) said...

Hi AdoUra

For Wcf this used to be now possible but now it is. One way is to use Wcf 4.0 and another is install this patch on 3.5 SP1:

http://support.microsoft.com/kb/971493/en-us

(it is the same usage)

I believe it is possible for Axis2 as well but not sure what is the configuration.

Unknown said...

when I run the wcf client, I got message:

Cannot find the X.509 cerfificate using the following search criteria. StoreName 'My', StoreLocation Current User', Find type: FindBySubjectDistinquishedName', 'FindValue', 'Cn=xwssecurityclient, OU=SUN, O=Internet Widgets Ply Ltd. S=Seom State C=AU"

also, how do I set certificate on client side?

Yaron Naveh (MVP) said...

Bin

this means the certificate is not installed in the location you refer to.

one known gotcha is that you installed the certificate in the current user store, but the IIS user is different than the one you log in with. The solution is to install in the local machien store and configure to take it from there.

Unknown said...

thanks, that get passed, server now is able to make the callback, but after that on WCF client, I got:

System.ServiceModel.Security.MessageSecurityException: An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail. ---> System.ServiceModel.FaultException: unknown
--- End of inner exception stack trace ---

Server stack trace:
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)

does that mean server is NOT sending response back to WCF client securely? if so, how to fix it?

Yaron Naveh (MVP) said...

turn on wcf trace and log on the server side and check:

1. does the server returns a correct response or a soap fault?

2. what exception - and inner exception - appear on the server log?

Anonymous said...

Hi,

thanks a lot for the example, Yaron.

Just one additional information. I tried the example using my own certificates and it worked well finally.

WCF had the problem to find my certificate. I changed the findValue of the certificate (CN= ... S=...) with the one that openSSL showed to me. OpenSSL returned an "ST=..." instead of "S=...". After changing this to "S=..." WCF was able to find the certificate.

Regards
Markus

Döme said...

Thanks for the example. We had a WCF client -> JAX-WS server. Your client configuration example prooved very useful. Once again thank you very much.

Mateusz Makowski said...

Hi Yaron,

Your sample is great, but I'm facing following problem:

"Cannot find a token authenticator for the 'System.IdentityModel.Tokens.X509SecurityToken' token type. Tokens of that type cannot be accepted according to current security settings."

I'm using Your certificates (imported to current user), client app. and in service yours src and services.xml.

The difference is that I'm using rampart-1.5 and VS2010 which has converted Your client app. Response from the service seems to be OK (checked by the tcp monitor).
Could You help me ?

Yaron Naveh (MVP) said...

Mateusz

please check this post:

http://webservices20.blogspot.com/2010/10/wcf-cannot-find-token-authenticator.html

can you verify the error is opn the response? how it looks like?

Mateusz Makowski said...

Hi Yaron,

Thx for advice. I've modified Your project with this tip, but now I get else error:

"The incoming message was signed with a token which was different from what used to encrypt the body. This was not expected."

For now I can't send request/response cause it's too big.

Btw. I'm using your certificates all the time.

Yaron Naveh (MVP) said...

Hi Mateusz

This usually means that the client does not have the server certificate defined in the clientCredentials behavior, or that it is defined to the wrong certificate.
Even if you use SignOnly make sure the client defines there the certificate used by the server to sign.

Mateusz Makowski said...

Hi Yaron,
this is my behaviour
< behavior name="NewBehavior">
< clientCredentials>
< clientCertificate findValue="xwssecurityclient" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />

< serviceCertificate >

< defaultCertificate findValue="xwssecurityserver" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
< authentication certificateValidationMode="None" revocationMode="NoCheck" trustedStoreLocation="LocalMachine"/>
< /serviceCertificate>
< /clientCredentials>
< /behavior>

And service part:
< ramp:signatureCrypto>
< ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin">
< ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type">JKS< /ramp:property>
< ramp:property name="org.apache.ws.security.crypto.merlin.file">C:\dotNet\keystore.jks< /ramp:property>
< ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">adminadmin< /ramp:property>

< /ramp:signatureCrypto>
< ramp:encryptionCypto>
< ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin">
< ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type">JKS< /ramp:property>
< ramp:property name="org.apache.ws.security.crypto.merlin.file">C:\dotNet\keystore.jks< /ramp:property>
< ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">adminadmin< /ramp:property>
< /ramp:crypto>
< /ramp:encryptionCypto>

Mateusz Makowski said...

Hi Yaron,
this is my behaviour
< behavior name="NewBehavior">
< clientCredentials>
< clientCertificate findValue="xwssecurityclient" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />

< serviceCertificate >

< defaultCertificate findValue="xwssecurityserver" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName" />
< authentication certificateValidationMode="None" revocationMode="NoCheck" trustedStoreLocation="LocalMachine"/>
< /serviceCertificate>
< /clientCredentials>
< /behavior>

And service part:
< ramp:signatureCrypto>
< ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin">
< ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type">JKS< /ramp:property>
< ramp:property name="org.apache.ws.security.crypto.merlin.file">C:\dotNet\keystore.jks< /ramp:property>
< ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">adminadmin< /ramp:property>




JKS
C:\dotNet\keystore.jks
adminadmin

Yaron Naveh (MVP) said...

please publish the request & response message.

I want to see if the request is encrypted and also if the response contains the signing key.

santhakumar said...

If it is possible to integrate wcf web service with smartclient gwt application

Yaron Naveh (MVP) said...

santhakumar

I have not used gwt. Since it runs from a broweser you would need to use basicHttpBinding or a RESTfull service style.

Haseeb said...

HI,
I have installed axis2 and rampart on my dedicated ubuntu server but cannot figure out how to run the server service ...can anyone please help me in setting this up..Thankyou so much and waiting for a reply
Regards,
Haseeb

Inder said...

I am calling IBM DataPower webservice and from WCF Client and getting same issue:

SecurityVersion.WSSecurityJan2004 does not support header encryption. Header with name 'ESBSubHeader' and namespace 'http://schema.walgreens.com/esbd/eia/esbSubHeader/v1' is configured for encryption. Consider using SecurityVersion.WsSecurity11 and above or use transport security to encrypt the full message.

Yaron Naveh (MVP) said...

Inder - try setting messageVersion to something with WSSecurity11 and copmpare the output message to a sample working message.

nicky said...

SecurityVersion.WSSecurityJan2004 does not support header encryption. Header with name 'ESBSubHeader' and namespace 'http://schema.walgreens.com/esbd/eia/esbSubHeader/v1' is configured for encryption. Consider using SecurityVersion.WsSecurity11 and above or use transport security to encrypt the full message.

I tried using WSSecurity11. but it was forming SecurityBindingElement as null and throwing null exception.

Milton said...

Yaron. I've been unable to generate a test certificate with SKI. Could you give me some lights on how to generate it? I've been using the certificates you provided, but would like to generate some self-signed certificates with a longer expiration date to go to prod.