In a the post Rampart basic examples - how you add WS-Security to Axis2 I listed all the great examples. In this post I'll actually run one of the samples and show the generated messages. I'll take the fourth sample Message integrity and non-repudiation with signature
since it's simple and adds great value with both integrity and authentication since only the sender can sign with the X509 certificate (except when the certificate is shared like here :-).
In the binary distribution of Rampart in the samples/basic
folder the README.txt
explains how to the run the samples:
You can use the ant build script provided here to run these samples.
Exmaple: Running sample - 01
- Start two shell instnaces and change to the directory where this file is
- To start the service:
$ ant service.01
- To run client:
$ ant client.01
--------------------------------------------------------------------------------
NOTE: To view the messages exchanged
- Change the "client.port" property in the "build.xml" to an available port
E.g. : >property name="client.port" value="9080"/<
- Setup tcpmon (http://ws.apache.org/commons/tcpmon/) to listen on the above
port and to point to port 8080 (value of the service.port property)
which is quite easy, though I needed to do a couple of small fixes.
The Service (serverside)
First I wanted to start the service/server. Here's what I did to get it running:
- setup the environment variable
AXIS2_HOME
. I first downloaded the Axis2 nightly to end up with a problem with running the client so I'll suggest you use Axis2 version 1.3.
- Prepare to show messages with TCPMon by changing the
client.port
property:
<property name="client.port" value="9999"/>
- In
<macrodef name="create.service.repo">
I changed:
<copy file="${modules.dir}/${rampart.mar}" tofile="${service.repos.dir}/sample@{sample.number}/modules/${rampart.mar}" overwrite="true"/>
to
<copy file="../../${rampart.mar}" tofile="${service.repos.dir}/sample@{sample.number}/modules/${rampart.mar}" overwrite="true"/>
- Added the following
fileset
to the classpath
on both the javac
and java
tasks:
<fileset dir="../../lib">
<include name="*.jar"/>
</fileset>
Then I was able to start the service (where <RAMPART_DIR> is where I unzipped Rampart-1.3):
$ ant service.04
Buildfile: build.xml
check.dependency:
service.04:
[copy] Copying 1 file to <RAMPART_DIR>/samples/basic/build/service_repositories/sample04/modules
[copy] Copying 1 file to <RAMPART_DIR>/samples/basic/build/service_repositories/sample04/modules
[javac] Compiling 2 source files to <RAMPART_DIR>/samples/basic/build/temp
[copy] Copying 1 file to <RAMPART_DIR>/samples/basic/build/temp/META-INF
[copy] Copying 1 file to <RAMPART_DIR>/samples/basic/build/temp
[copy] Copying 1 file to <RAMPART_DIR>/samples/basic/build/temp
[jar] Building jar: <RAMPART_DIR>/samples/basic/build/service_repositories/sample04/services/sample04.aar
[delete] Deleting directory <RAMPART_DIR>/samples/basic/build/temp
[java] [SimpleHTTPServer] Starting
[java] [SimpleHTTPServer] Using the Axis2 Repository <RAMPART_DIR>/samples/basic/build/service_repositories/sample04
[java] [SimpleHTTPServer] Listening on port 8080
[java] 2008-01-11 20:21:10,948 INFO org.apache.axis2.deployment.ModuleDeployer - Deploying module: addressing-SNAPSHOT - file:<RAMPART_DIR>/samples/basic/build/service_repositories/sample04/modules/addressing-SNAPSHOT.mar
[java] 2008-01-11 20:21:11,737 INFO org.apache.axis2.deployment.ModuleDeployer - Deploying module: rampart-1.3 - file:<RAMPART_DIR>/samples/basic/build/service_repositories/sample04/modules/rampart-1.3.mar
[java] 2008-01-11 20:21:12,036 INFO org.apache.axis2.deployment.ServiceDeployer - Deploying Web service: sample04.aar - file:<RAMPART_DIR>/samples/basic/build/service_repositories/sample04/services/sample04.aar
[java] 2008-01-11 20:21:12,096 INFO org.apache.axis2.transport.http.server.DefaultConnectionListener - Listening on port 8080
[java] [SimpleHTTPServer] Started
The client
Running the client is very much like the service, though I first got this error when I used the Axis2 nightly:
[java] Exception in thread "main" org.apache.axis2.deployment.DeploymentException: javax/jms/BytesMessage
[java] at org.apache.axis2.deployment.AxisConfigBuilder.processTransportSenders(AxisConfigBuilder.java:596)
[java] at org.apache.axis2.deployment.AxisConfigBuilder.populateConfig(AxisConfigBuilder.java:117)
[java] at org.apache.axis2.deployment.DeploymentEngine.populateAxisConfiguration(DeploymentEngine.java:628)
[java] at org.apache.axis2.deployment.FileSystemConfigurator.getAxisConfiguration(FileSystemConfigurator.java:115)
[java] at org.apache.axis2.context.ConfigurationContextFactory.createConfigurationContext(ConfigurationContextFactory.java:64)
[java] at org.apache.axis2.context.ConfigurationContextFactory.createConfigurationContextFromFileSystem(ConfigurationContextFactory.java:180)
[java] at org.apache.rampart.samples.sample04.Client.main(Unknown Source)
[java] Caused by: java.lang.NoClassDefFoundError: javax/jms/BytesMessage
[java] at java.lang.Class.getDeclaredConstructors0(Native Method)
[java] at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
[java] at java.lang.Class.getConstructor0(Class.java:2699)
[java] at java.lang.Class.newInstance0(Class.java:326)
[java] at java.lang.Class.newInstance(Class.java:308)
[java] at org.apache.axis2.deployment.AxisConfigBuilder.processTransportSenders(AxisConfigBuilder.java:581)
[java] ... 6 more
[java] Java Result: 1
looks like theree's been some changes to the deployment file format though I haven't checked it out. After also doing the last two steps for the serverside for the clientside target I was able to run the client:
[copy] Copying 1 file to <RAMPART_DIR>/samples/basic/build/client_repositories/sample04/conf
[copy] Copying 1 file to <RAMPART_DIR>/samples/basic/build/client_repositories/sample04/modules
[copy] Copying 1 file to <RAMPART_DIR>/samples/basic/build/client_repositories/sample04/modules
[copy] Copying 1 file to <RAMPART_DIR>/samples/basic/build/temp_client
[copy] Copying 1 file to <RAMPART_DIR>/samples/basic/build/temp_client
[java] <ns:echoResponse xmlns:ns="http://sample04.samples.rampart.apache.org"<>ns:return>Hello world</ns:return></ns:echoResponse>
Nice, but hard to tell whether WS-Security actually was used so let's have a look at the messages that was exchanged.
The messages
Request
The request had the following HTTP headers:
POST /axis2/services/sample04 HTTP/1.1
Content-Type: text/xml; charset=UTF-8
SOAPAction: "urn:echo"
User-Agent: Axis2
Host: localhost:9999
Transfer-Encoding: chunked
and the SOAP request, where the SOAP-header carries the WS-Security elements:
1 <?xml version='1.0' encoding='UTF-8'?>
2 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
3 <soapenv:Header>
4 <wsse:Security
5 xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
6 soapenv:mustUnderstand="1">
7 <wsse:BinarySecurityToken
8 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
9 EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
10 ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
11 wsu:Id="CertId-148082">
12 MIICTDC....UiaNKiQiu16JCnxc8tGSw3nSPg44aLYmA==
13 </wsse:BinarySecurityToken>
14 <ds:Signature
15 xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
16 Id="Signature-21878616">
17 <ds:SignedInfo>
18 <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
19 <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
20 <ds:Reference URI="#id-24778599">
21 <ds:Transforms>
22 <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
23 </ds:Transforms>
24 <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
25 <ds:DigestValue>aIRDYzmMgF/dcP7cUJS6B6T7q8k=</ds:DigestValue>
26 </ds:Reference>
27 </ds:SignedInfo>
28 <ds:SignatureValue>
29 TVbeyvg....9SH/13k1qpki9...+ZZM+9sIsFs=
30 </ds:SignatureValue>
31 <ds:KeyInfo Id="KeyId-6400263">
32 <wsse:SecurityTokenReference
33 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
34 wsu:Id="STRId-3115866">
35 <wsse:Reference
36 URI="#CertId-148082"
37 ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
38 </wsse:SecurityTokenReference>
39 </ds:KeyInfo>
40 </ds:Signature>
41 <wsu:Timestamp
42 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
43 wsu:Id="Timestamp-20735553">
44 <wsu:Created>2008-01-11T19:46:23.656Z</wsu:Created>
45 <wsu:Expires>2008-01-11T19:51:23.656Z</wsu:Expires>
46 </wsu:Timestamp>
47 </wsse:Security>
48 </soapenv:Header>
49 <soapenv:Body
50 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
51 wsu:Id="id-24778599">
52 <ns1:echo xmlns:ns1="http://sample04.samples.rampart.apache.org">
53 <param0>Hello world</param0>
54 </ns1:echo>
55 </soapenv:Body>
56 </soapenv:Envelope>
Response
The response had these HTTP headers:
HTTP/1.1 200 OK
Date: Fri, 11 Jan 2008 19:46:24 GMT
Server: Simple-Server/1.1
Transfer-Encoding: chunked
Content-Type: text/xml; charset=UTF-8
and the SOAP response which is symmetrical to the request:
1 <?xml version='1.0' encoding='UTF-8'?>
2 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
3 <soapenv:Header>
4 <wsse:Security
5 xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
6 soapenv:mustUnderstand="1">
7 <wsse:BinarySecurityToken
8 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
9 EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
10 ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
11 wsu:Id="CertId-2150700">
12 MIICTjCCAbcCBEbJZQEw....AqNbjO7+Jbm6+3pyYagQoBpdHZLnR....A3+5xl4VI.......bGxa4+vIbbV4CaUG5s5x
13 </wsse:BinarySecurityToken>
14 <ds:Signature
15 xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
16 Id="Signature-6302571">
17 <ds:SignedInfo>
18 <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
19 <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
20 <ds:Reference URI="#id-26343425">
21 <ds:Transforms>
22 <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
23 </ds:Transforms>
24 <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
25 <ds:DigestValue>f0hkA2SGmWtioGBaLwlfsGbSgMk=</ds:DigestValue>
26 </ds:Reference>
27 <ds:Reference URI="#SigConf-18206828">
28 <ds:Transforms>
29 <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
30 </ds:Transforms>
31 <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
32 <ds:DigestValue>W1coTKqCERwIlbeiGL83w7pAEi4=</ds:DigestValue>
33 </ds:Reference>
34 </ds:SignedInfo>
35 <ds:SignatureValue>
36 IgzqToPMv...ZNrYDe/29JFnAkl....BAYOZMtCPs2XG0btNpX2BegULxk=
37 </ds:SignatureValue>
38 <ds:KeyInfo Id="KeyId-7435043">
39 <wsse:SecurityTokenReference
40 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
41 wsu:Id="STRId-4070344">
42 <wsse:Reference
43 URI="#CertId-2150700"
44 ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
45 </wsse:SecurityTokenReference>
46 </ds:KeyInfo>
47 </ds:Signature>
48 <wsu:Timestamp
49 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
50 wsu:Id="Timestamp-18092261">
51 <wsu:Created>2008-01-11T19:46:24.558Z</wsu:Created>
52 <wsu:Expires>2008-01-11T19:51:24.558Z</wsu:Expires>
53 </wsu:Timestamp>
54 <wsse11:SignatureConfirmation
55 xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"
56 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
57 Value="TVbeyvgLy...1QgDj8Nau0Fp+ZZM+9sIsFs="
58 wsu:Id="SigConf-18206828" />
59 </wsse:Security>
60 </soapenv:Header>
61 <soapenv:Body
62 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
63 wsu:Id="id-26343425">
64 <ns:echoResponse xmlns:ns="http://sample04.samples.rampart.apache.org">
65 <ns:return>Hello world</ns:return>
66 </ns:echoResponse>
67 </soapenv:Body>
68 </soapenv:Envelope>
Looking at the configuration for the serverside:
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>
I can be seen that in verifying the request there's a demand for the Timestamp
and the certificate used for the signature to be accepted based on the properties in service.properties
. In this specific request the public part is embedded in the BinarySecurityToken
and only the path or the specific certificate is to be checked.
In the response the DirectReference
makes the public part of the X509 certificate embedded with BinarySecurityToken
and the password callback is needed to access the private key for creating the signature.