Friday, December 21, 2007

Rampart basic examples - how you add WS-Security to Axis2

pencil icon, that"s clickable to start editing the post

In my personal opinion Web Services Security is the most successful addition to the web service SOAP stack, often called WS-*. It was much needed and avoided to run into conflicts between the big market players, which to the contrary one of the other much needed abilities, that of adding reliability, ran into big time. Some might argue that WS-Addressing is equally successful and it is important, but for one the standardization process took much longer and secondly (again a personal one) I've primarily been using web services in synchronous mode (in-out) and not in complex flows, so I've not had much need for it though I've had to live with it.

It's been some time since I last used WS-Security and it was back in the early days of WSS4J and Axis1. In the meantime Axis2 has evolved with a new architecture and nice features like native XMLBeans support. For WS-Security it's still WSS4J with support for Web Services Security v1.0 (March 2004), and as far as I can tell support for Web Services Security v1.1 (February 2006) is not that far away. With Axis2 the days of adding handlers and adding parameters with generic name/value constructs are over. Now the Axis2 architecture is build on Flows, Phases, Handlers, and Modules (From the OxygenTank) and there's a seperate module, called Rampart, that plugs WS-Security support with WSS4J into Axis2. The Axis2 guide for using rampart: Securing SOAP Messages with Rampart practically covers it all, but for new comers there's a great set of samples covering about just all practical scenarios of using WS-Security. In this post I give an quick overview over these samples.

Note: Rampart does have it's own subsite, but it does not look like it's being maintained since the last release here is still 1.2.

Basic samples

There are 11 examples bundled with the current Rampart. It's all configured with two parameters named InflowSecurity and OutflowSecurity in the files services.xml (server side) and axis2.xml (client side). I'll now go through all of them with the central configurations and a mix of the comments that come with the samples and my own. I'll not show any of the code, for that you'll have to look at the samples yourself.

01. Rampart Engaged and no configuration

The first sample actually does NOT add WS-Security, and shows the basic service that's used and the needed Axis2 configuration. Thereby also showing that Apache Rampart does not work on the messages when simply engaged without any configuration (parameters).

In this post I'll only show the server side configuration since it's almost identical to the client side. For this sample the services.xml file looks like:

    1 <?xml version="1.0" encoding="UTF-8"?>
    2 <!--
    3   !
    4   ! Copyright 2006 The Apache Software Foundation.
    5   !
    6   ! Licensed under the Apache License, Version 2.0 (the "License");
    7   ! you may not use this file except in compliance with the License.
    8   ! You may obtain a copy of the License at
    9   !
   10   !      http://www.apache.org/licenses/LICENSE-2.0
   11   !
   12   ! Unless required by applicable law or agreed to in writing, software
   13   ! distributed under the License is distributed on an "AS IS" BASIS,
   14   ! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15   ! See the License for the specific language governing permissions and
   16   ! limitations under the License.
   17   !-->
   18 <!-- services.xml of sample-1 : No Security-->
   19 <service>
   20   <operation name="echo">
   21     <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
   22   </operation>
   23   <parameter
   24     name="ServiceClass"
   25     locked="false">
   26     org.apache.rampart.samples.sample01.SimpleService
   27   </parameter>
   28 
   29   <module ref="rampart" />
   30 
   31 </service>

So adding the module doesn't do nothing in itself, contrary to the behavior of WS-Addressing.

02. UsernameToken authentication

The client is configured to add a UsernameToken to the outgoing message. The service is configured to process it.

From now I'll just show the WS-Security parameters to keep it short and focused:

   32   <parameter name="InflowSecurity">
   33     <action>
   34       <items>UsernameToken Timestamp</items>
   35       <passwordCallbackClass>org.apache.rampart.samples.sample02.PWCBHandler</passwordCallbackClass>
   36     </action>
   37   </parameter>

Note how org.apache.rampart.samples.sample02.PWCBHandler supplies the password to wss4j to compute the digest for comparison.

03. UsernameToken authentication with a plain text password

The client is configured to add a UsernameToken to the outgoing message. Note the <passwordType>PasswordText</passwordType> element. The service is configured to process it.

Note how org.apache.rampart.samples.sample03.PWCBHandler authenticates the password

   32   <parameter name="InflowSecurity">
   33     <action>
   34       <items>UsernameToken</items>
   35       <passwordCallbackClass>org.apache.rampart.samples.sample03.PWCBHandler</passwordCallbackClass>
   36     </action>
   37   </parameter>

04. Message integrity and non-repudiation with signature

Both client and servce are configured to sign the outgoing message and to verify the signature of the incoming message using their key pairs.

   32   <parameter name="InflowSecurity">
   33     <action>
   34       <items>Timestamp Signature</items>
   35       <signaturePropFile>service.properties</signaturePropFile>
   36     </action>
   37   </parameter>
   38 
   39   <parameter name="OutflowSecurity">
   40     <action>
   41       <items>Timestamp Signature</items>
   42       <user>service</user>
   43       <passwordCallbackClass>org.apache.rampart.samples.sample04.PWCBHandler</passwordCallbackClass>
   44       <signaturePropFile>service.properties</signaturePropFile>
   45       <signatureKeyIdentifier>DirectReference</signatureKeyIdentifier>
   46     </action>
   47   </parameter>

05. Encryption

Both client and servce are configured to encrypt the outgoing message and to decrypt incoming message using their key pairs.

   32   <parameter name="InflowSecurity">
   33     <action>
   34       <items>Encrypt</items>
   35       <passwordCallbackClass>org.apache.rampart.samples.sample05.PWCBHandler</passwordCallbackClass>
   36       <decryptionPropFile>service.properties</decryptionPropFile>
   37     </action>
   38   </parameter>
   39 
   40   <parameter name="OutflowSecurity">
   41     <action>
   42       <items>Encrypt</items>
   43       <encryptionUser>client</encryptionUser>
   44       <encryptionPropFile>service.properties</encryptionPropFile>
   45     </action>
   46   </parameter>

06. Sign and encrypt a messages

Both client and servce are configured to first sign and then encrypt the outgoing message and to decrypt and verify the incoming message using their key pairs.

   32   <parameter name="InflowSecurity">
   33     <action>
   34       <items>Timestamp Signature Encrypt</items>
   35       <passwordCallbackClass>org.apache.rampart.samples.sample06.PWCBHandler</passwordCallbackClass>
   36       <signaturePropFile>service.properties</signaturePropFile>
   37     </action>
   38   </parameter>
   39 
   40   <parameter name="OutflowSecurity">
   41     <action>
   42       <items>Timestamp Signature Encrypt</items>
   43       <user>service</user>
   44       <passwordCallbackClass>org.apache.rampart.samples.sample06.PWCBHandler</passwordCallbackClass>
   45       <signaturePropFile>service.properties</signaturePropFile>
   46       <signatureKeyIdentifier>DirectReference</signatureKeyIdentifier>
   47       <encryptionKeyIdentifier>SKIKeyIdentifier</encryptionKeyIdentifier>
   48       <encryptionUser>useReqSigCert</encryptionUser>
   49     </action>
   50   </parameter>

07. Encrypt and sign messages

Both client and servce are configured to first encrypt and then sign the outgoing message and to verify and decrypt the incoming message using their key pairs.

   32   <parameter name="InflowSecurity">
   33     <action>
   34       <items>Timestamp Encrypt Signature</items>
   35       <passwordCallbackClass>org.apache.rampart.samples.sample07.PWCBHandler</passwordCallbackClass>
   36       <signaturePropFile>service.properties</signaturePropFile>
   37     </action>
   38   </parameter>
   39 
   40   <parameter name="OutflowSecurity">
   41     <action>
   42       <items>Timestamp Encrypt Signature</items>
   43       <user>service</user>
   44       <passwordCallbackClass>org.apache.rampart.samples.sample07.PWCBHandler</passwordCallbackClass>
   45       <signaturePropFile>service.properties</signaturePropFile>
   46       <signatureKeyIdentifier>DirectReference</signatureKeyIdentifier>
   47       <encryptionKeyIdentifier>SKIKeyIdentifier</encryptionKeyIdentifier>
   48       <encryptionUser>useReqSigCert</encryptionUser>
   49     </action>
   50   </parameter>

08. Signing twice

The client is configured to sign the outgoing message twice. Note the aditional <action>> element that defines the second signature (client side) and that we simply use "Signature Signature" as action items (server side - here).

   32   <parameter name="InflowSecurity">
   33     <action>
   34       <items>Timestamp Signature Signature</items>
   35       <passwordCallbackClass>org.apache.rampart.samples.sample08.PWCBHandler</passwordCallbackClass>
   36       <signaturePropFile>service.properties</signaturePropFile>
   37     </action>
   38   </parameter>

09. Encryption with a key known to both parties

Encryption with a key known to both parties. Both client and servce are configured to encrypt the outgoing message and to decrypt incoming message using a known named key.

Note the use of <EmbeddedKeyName>SessionKey</EmbeddedKeyName> and that org.apache.rampart.samples.sample09.PWCBHandler sets the key

   32   <parameter name="InflowSecurity">
   33     <action>
   34       <items>Encrypt</items>
   35       <passwordCallbackClass>org.apache.rampart.samples.sample09.PWCBHandler</passwordCallbackClass>
   36       <decryptionPropFile>service.properties</decryptionPropFile>
   37     </action>
   38   </parameter>
   39 
   40   <parameter name="OutflowSecurity">
   41     <action>
   42       <items>Encrypt</items>
   43       <user>service</user>
   44       <encryptionKeyIdentifier>EmbeddedKeyName</encryptionKeyIdentifier>
   45       <encryptionPropFile>service.properties</encryptionPropFile>
   46       <EmbeddedKeyCallbackClass>org.apache.rampart.samples.sample09.PWCBHandler</EmbeddedKeyCallbackClass>
   47       <EmbeddedKeyName>SessionKey</EmbeddedKeyName>
   48     </action>
   49   </parameter>

10. MTOM Optimizing base64 content in the secured message

Sign and encrypt messages. Both client and servce are configured to first sign and then encrypt the outgoing message and to decrypt and verify the incoming message using their key pairs.

Note the use of <optimizeParts>[xpath expression]</optimizeParts>

   32   <parameter name="InflowSecurity">
   33     <action>
   34       <items>Timestamp Signature Encrypt</items>
   35       <passwordCallbackClass>org.apache.rampart.samples.sample10.PWCBHandler</passwordCallbackClass>
   36       <signaturePropFile>service.properties</signaturePropFile>
   37     </action>
   38   </parameter>
   39 
   40   <parameter name="OutflowSecurity">
   41     <action>
   42       <items>Timestamp Signature Encrypt</items>
   43       <user>service</user>
   44       <passwordCallbackClass>org.apache.rampart.samples.sample10.PWCBHandler</passwordCallbackClass>
   45       <signaturePropFile>service.properties</signaturePropFile>
   46       <signatureKeyIdentifier>DirectReference</signatureKeyIdentifier>
   47       <encryptionKeyIdentifier>SKIKeyIdentifier</encryptionKeyIdentifier>
   48       <encryptionUser>useReqSigCert</encryptionUser>
   49     </action>
   50   </parameter>

11. Dynamic configuration : Get rid of the config files ... let's use code!

Both client and servce are configured to first sign and then encrypt the outgoing message and to decrypt and verify the incoming message using their key pairs.

Note that we don't use any parameters in the client.axis2.xml, see org.apache.rampart.samples.sample11.Client's getOutflowConfiguration() and getInflowConfiguration() methods and their usage.

   32   <parameter name="InflowSecurity">
   33     <action>
   34       <items>Timestamp Signature Encrypt</items>
   35       <passwordCallbackClass>org.apache.rampart.samples.sample11.PWCBHandler</passwordCallbackClass>
   36       <signaturePropFile>service.properties</signaturePropFile>
   37     </action>
   38   </parameter>
   39 
   40   <parameter name="OutflowSecurity">
   41     <action>
   42       <items>Timestamp Signature Encrypt</items>
   43       <user>service</user>
   44       <passwordCallbackClass>org.apache.rampart.samples.sample11.PWCBHandler</passwordCallbackClass>
   45       <signaturePropFile>service.properties</signaturePropFile>
   46       <signatureKeyIdentifier>DirectReference</signatureKeyIdentifier>
   47       <encryptionKeyIdentifier>SKIKeyIdentifier</encryptionKeyIdentifier>
   48       <encryptionUser>useReqSigCert</encryptionUser>
   49     </action>
   50   </parameter>

15 comments :

aaron said...

i just started looking at rampart. i'm pretty new to axis2 and especially rampart. anyway, i was wondering if you could give me a quick hint on why the signing examples doesn't work. i assume its because i don't have some sort of cert setup. but not sure which ones.

thanks!

Sweetxml said...

Hi Aaron

I this post I just went through the configurations for the samples for a brush up. I've wanted to run a demo with it but hadn't found the time. Your comment made me plunge in and try out the signature sample which you can see in Runnning the Axis2 Rampart sample "04. Message integrity and non-repudiation with signature".

Best regards
Brian

Nandana Mihindukulasooriya said...

Hi Brian
Wow, this is a great post describing the Rampart usage. I suggest you to go through the policy samples too and it would be great if you can blog about those samples too. Parameter based Rampart configuration is sort of deprecated now. Policy based Rampart configuration is much more powerful and much more interoperable too. You can directly interoperate with .NET, C, PHP , ... web services as security policy will be there in WSDL and it is the same for any web service which uses WS-Security Policy Language for configuration. Policy based configuration is not as much as human readable as parameter based configuration though :).

Sweetxml said...

Hi Nandana

Thanks for your feedback. I have looked at the policy examples and I'm in the process of writing a post on them. I choose the basic examples first because they look very similar to the old syntax that I'm familiar with. I agree with you that a common configuration syntax with Policy is the way to go. The syntax though is much more verbose and the policy samples are much more advanced and not parallel with the basic ones since they involve WS-SecureConversation and WS-Trust with the Rahas module.

Best regards
Brian

Pritesh Agrawal said...

Hello Brain,

This Artical is really useful to me. Could u please suggest some book to me for ws-security.

Sweetxml said...

Hi Pritesh Agrawal

Thank you, I'm glad it was of use to you . I did little though but to just cut out the most essential parts from the distribution.

Whereas for books, I'm sorry, but I can't help you since I haven't read any. My suggestion to you would be to run the samples and log and review the messages send and received, otherwise browse for other examples there are quite a few both on Axis/Rampart and WSE or what ever it's called nowadays.

Best regards
Brian

Anonymous said...

Hi Pritesh Agrawal,
If you are looking for tutorials on Apache Rampart, WSO2 Developer portal is also a good place to look at. Please take a look at "Apache Rampart" and "Rampart > Java" tags in the Oxygen Tank library.

Dutchman said...

Hi sweetxml,

Thank you for this topic. It was very useful for me to get started on using Rampart in my web service. I would like to know more about how a .NET client would send the security credentials to a Axis2 web service using Rampart. Can you please provide info/pointers to this? The examples I see focus on a combination of Axis2 service and Axis2 client.

Thanks in advance.

Sweetxml said...

Hi Dutchman

Thank you for your comment, glad to hear that it was of help to you.

You're right that my blogpost had sole focus on the Axis2/Java. My knowledge on .NET webservice technologies is a little dated (something I expect to catch up on before new year), but I guess it depends on platform/version. My last tryout was with WSE that had tools for generating code stubs from WSDL and the options to control applying WSS/WSA with WS-SecurityPolicy. I think that with with .NET version 3/3.5 it's been wrapped into WCF. A quick search on "WCF WS-Security" found the interop blog post called WCF: WS-Security, SSL, TransportWithMessageCredentials, Message Logging - maybe that'll help you get started.
You're welcome to re-comment on the specific version/framework that you expect to be working with.

Best regards
Brian

ATUL said...

Hi,
I am new to Rampart but implemented all what is said in web sites. I am able to get plain soap msg in soapmonitor but no encrypted msg, I am using Timestamp Signature Encrypt

Pl help

Atul

Sweetxml said...

Hi ATUL

I have all ways used TcpMon, since it's external to both the server and client and easy to use. I am sure SOAP Monitor is fine, but I just have no knowledge about it.

I'm not sure what you're exact problem is, but I did a quick search and found a post where Werner had a reply that might be relevant to you Re: Verifying SOAP response headers: msg#00088. Other than that I'll recommend you to try TcpMon and the samples that come with wss4j/rampart.

Best Regards
Brian

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

locksmith in brisbane said...



Very interesting topic will bookmark your site to check if you write more about in the future.

Unknown said...

I’ll never ever miss the chance to read your new blogs. Glittering work guys!!
frontpoint security reviews

Sanjeev said...

Very nice post. Although I have one query:

I have implemented WS Security using Axis2 and Rampart1.6.2.

While implementing I learned that the Webservice having security headers can accept the request only when the request is sent on SSL (or HTTPS).

Now my client is having problem in Securizing (on SSL) its different communication channels, so they are asking me if its possible to sent request on HTTP on the service implementing WS Security ?