Web Services Security with Apache Rampart – Part 2 (Message-Level Security)

Apache Rampart is the Axis2 module that provides WS-Security functionality to Axis2 Web services and clients. Rampart currently implements WS-SOAP message security , WS-Security policy , WS-Secure conversation and WS-Trust specifications. In part one of this tutorial, we looked at applying transport-level security to a Web service and a client. In this tutorial, we will look at how to apply message-level security to a Web service and a client using Apache Rampart.

Date: Wed, 26th Mar, 2008
Level: Introductory
Reads: 47550 Comments: 30 | Login or register to post comments
Nandana Mihindukulasooriya
Tech Lead
WSO2 Inc.

Introduction

This tutorial is a step by step guide on how to sign a SOAP message with Apache Rampart using policy based configuration. We will also look at how to deploy the Apache Rampart module in Axis2. Although we have already covered deploying Rampart in Axis2, in part one of this tutorial, it is repeated here again for completeness sake only. Those who have already deployed Rampart can skip this section. We will then go and look at how a Axis2 Web service and a client can be secured with Rampart. As Axis2/Rampart has been proven to be highly interoperable, either the Web service or the client can still be written in some other Web service stack (including .NET / C / PHP) other than Axis2/Java.

See Web Services Security with Apache Rampart – Part 1 (Transport Level Security) for part I of this tutorial.

Applies To

<Project/lan> version
Apache Rampart 1.3
Apache Axis2 1.3

Table of Contents

Scenario

In this tutorial we will look at a scenario where SOAP messages will be signed. Signing SOAP messages ensures authentication, integrity and non-repudiation. As you could observe from the diagram given below a service and a client trusts each other, and have each other’s certificates in their key stores.

Scenario Image

We will use the Axis2 WAR deployed in Apache Tomcat server for this tutorial, as it is one of the most common use cases.

Deploying the Rampart Module

Deploying the module and necessary jars

If you have read part one of this tutorial and have successfully deployed Rampart in Axis2, then you can skip this section and jump directly to the section titled “Securing the Service”.
Apache Rampart 1.3 binary distribution can be downloaded from here. Rampart distribution contains two module files, rampart-1.3 and rahas-1.3.mar . These module files should be copied to the modules directory of the Axis2 engine that can be found in TOMCAT_HOME/webapps/axis2/WEB-INF/modules, where TOMCAT_HOME is the home directory of the Apache Tomcat server in which Axis2 war is deployed. All the dependancy jars needed for Apache Rampart can be found under the libs directory of the Rampart distribution. These need to be copied to the lib directory of the Axis2 engine, which can found in TOMCAT_HOME/webapps/axis2/WEB-INF/lib.
You can check whether Apache Rampart is successfully deployed by logging in to Axis2 as the admin and using the System Components/available modules option in admin Web console . Both "rampart" and "rahas" should be listed under available modules, if you deploying of  rampart and rahas modules has been successfull.

Securing the Service

Step 1. Writing the Web service and the service descriptor

We will use the same simple service we used in part one of this tutorial for in this section as well. It has a single operation called "add" that adds two integers and returns the sum of them. We will be using the code first approach for this tutorial for simplicity. Service implementation class is given below.

package tutorial.rampart.service;

/**
 * Secure Service implementation class
 */
public class SecureService {
	
	public int add(int a, int b) {
		return a+b;
	}

}

Service descriptor for the above mentioned service is given below. You can find more information on how to write an Axis2 Web service in the tutorial titled "Hello world with Apache Axis2".

<service>
  <module ref="rampart"/>
  <parameter name="ServiceClass" locked="false">tutorial.rampart.service.SecureService</parameter>
  <operation name="add">
    <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
  </operation>
</service>

Step 2. Setting up the key store

To sign messages back and forth, both the client and the service need to posses public-private key pairs. In this tutorial we will be using X509 certificates for both the client and the service. How to create key pairs and import them to key stores is out of the scope of this tutorial and you can find that information in another tutorial titled “Setting Up Keystores for a Client and a Service”. The service.jks which we use as the key store of the service, can be downloaded with the source code of this tutorial. You can use the keytool shipped with Java if you want inspect the keystore and see what keys it contains.


$ keytool -list -v -keystore path/to/service.jks -storepass servicePW 
 
Keystore type: jks
Keystore provider: SUN
 
Your keystore contains 2 entries
 
Alias name: service
Creation date: Mar 21, 2008
Entry type: keyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=service, OU=Secuirty Team, O=WSO2, L=colombo, ST=Western, C=LK, EMAILADDRESS=service@wso2.com
Issuer: CN=service, OU=Secuirty Team, O=WSO2, L=colombo, ST=Western, C=LK, EMAILADDRESS=service@wso2.com
Serial number: 47e3b6c0
Valid from: Fri Mar 21 18:53:12 LKT 2008 until: Tue Mar 15 18:53:12 LKT 2033
Certificate fingerprints:
         MD5:  C4:B9:2D:70:22:E9:08:6B:07:3B:2C:1E:5B:87:ED:09
         SHA1: 4F:C9:0C:42:01:B7:BE:AC:0D:4F:AC:00:A2:E7:CC:CA:07:40:8E:BB
 
 
*******************************************
*******************************************
 
 
Alias name: client
Creation date: Mar 21, 2008
Entry type: trustedCertEntry
 
Owner: CN=client, OU=Secuirty Team, O=WSO2, L=colombo, ST=Western, C=LK, EMAILADDRESS=client@wso2.com
Issuer: CN=client, OU=Secuirty Team, O=WSO2, L=colombo, ST=Western, C=LK, EMAILADDRESS=client@wso2.com
Serial number: 47e3b631
Valid from: Fri Mar 21 18:50:49 LKT 2008 until: Tue Mar 15 18:50:49 LKT 2033
Certificate fingerprints:
         MD5:  DE:66:EB:95:18:2E:44:97:05:CE:DF:FC:83:E9:53:C3
         SHA1: CE:E5:F0:BB:2F:46:A9:F0:45:60:4C:16:1B:33:FC:B5:09:0B:8C:13
 
 
*******************************************
*******************************************

As you can see, service.jks contains it’s public-private key and the public key of client as trusted certificates. Service needs it’s private key to sign the messages which is pretty obvious but why does it need the certificate of the client? It is because it needs the client’s public key to verify the signature of the client.

Step 3. Writing the password callback

In part one of this tutorial, we used a password callback for the service to authenticate the username tokens. You might be wondering why we need to write a password callback class for this scenario as we are not using username tokens. The use of password callback class here is different to its use in the previous tutorial. As you already know, we need the private key of the service to sign SOAP messages. Each private key has a password associated with it. In order to retrieve the private key, we need to provide the password of the relevant key and this password callback class is used for that purpose. The password callback class used in this tutorial is given below. Even though passwords are hard coded in this example, they can also be retrieved from a database, a LDAP server or any other storage by writing the relevant password retrieval logic in the password callback class.

package tutorial.rampart.service;

import org.apache.ws.security.WSPasswordCallback;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import java.io.IOException;

public class PWCBHandler implements CallbackHandler {

    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {

        for (int i = 0; i < callbacks.length; i++) {
            
            // To use the private key to sign messages, we need to provide 
        	// the private key password 
            WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
               
            if(pwcb.getIdentifer().equals("service") ) {
            	pwcb.setPassword("servicePW");
                return;
            }         
        }
    }
}

Step 4. Constructing the security policy

We will be using the policy based configuration approach of Apache Rampart for this tutorial. So, we should construct a suitable security policy using WS-Security policy language to define the requirements of the Web service. The security policy used in this tutorial is given below. 

<wsp:Policy wsu:Id="SigOnly" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
  <wsp:ExactlyOne>
    <wsp:All>
      <sp:AsymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
        <wsp:Policy>
          <sp:InitiatorToken>
            <wsp:Policy>
              <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never">
                <wsp:Policy>
                  <sp:WssX509V3Token10/>
                </wsp:Policy>
              </sp:X509Token>
            </wsp:Policy>
          </sp:InitiatorToken>
          <sp:RecipientToken>
            <wsp:Policy>
              <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never">
                <wsp:Policy>
                  <sp:WssX509V3Token10/>
                </wsp:Policy>
              </sp:X509Token>
            </wsp:Policy>
          </sp:RecipientToken>
          <sp:AlgorithmSuite>
            <wsp:Policy>
              <sp:TripleDesRsa15/>
            </wsp:Policy>
          </sp:AlgorithmSuite>
          <sp:Layout>
            <wsp:Policy>
              <sp:Strict/>
            </wsp:Policy>
          </sp:Layout>
          <sp:IncludeTimestamp/>
          <sp:OnlySignEntireHeadersAndBody/>
        </wsp:Policy>
      </sp:AsymmetricBinding>
      <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
        <sp:Body/>
      </sp:SignedParts>
    </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

As you can see, the above security policy contains two main security assertions: an asymmetric binding assertion and a signed parts assertion. Asymmetric binding defines what keys to be used and a few additional properties such as which algorithms to be used in cryptographic operations, layout of the security header, etc. Signed parts assertion defines what parts of the message should be signed. In this tutorial we will be signing the SOAP body of the message.
More information on WS-Security Policy language and how we can construct security policies to suit our security requirements can be found in the article titled ”Understanding WS – Security Policy Language”.

Step 5. Providing Rampart specific configuration details

Rampart uses a custom assertion called RampartConfig assertion to provide Rampart specific configuration details to Rampart Engine. RampartConfig for this tutorial is given below. 

<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
    <ramp:user>service</ramp:user>
    <ramp:passwordCallbackClass>tutorial.rampart.service.PWCBHandler</ramp:passwordCallbackClass>
    <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">path/to/service.jks</ramp:property>
            <ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">servicePW</ramp:property>
        </ramp:crypto>
    </ramp:signatureCrypto>
</ramp:RampartConfig>

<ramp:user/> provides the alias of the key that should be used to sign the messages. As we have already seen in the listing of service.jks, private key alias of the service is “service”. <ramp:passwordCallbackClass> provides the password callback class which is used to retrieve the private key password. <ramp:signatureCrypto> carries information on the key store used to retrieve keys to create and verify signatures. These information include crypto provider, key store type, key store file and the key store password. (Note that this is the password of the key store and not the password of the private key).

Step 6. Engaging Rampart and applying the security policy

Now, we will look at how we can engage Rampart to the Web service and apply the security policy. This is done completly using the service descriptor. We don't have to modify the source of the Web service to secure it. First, we engage the Rampart module to the Web service adding  <module ref="rampart"/> element to the service descriptor. Then, we apply security by adding the policy to the service descriptor. Modified service descriptor after engaging Rampart and applying the policy is given below. Elements within the policy element are not shown for brevity. 

<service>
  <module ref="rampart"/>
  <parameter name="ServiceClass" locked="false">tutorial.rampart.service.SecureService</parameter>
  <operation name="add">
    <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
  </operation>
  <wsp:Policy wsu:Id="UTOverTransport" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
    <wsp:ExactlyOne>
      <wsp:All>
        <sp:AsymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"> </sp:AsymmetricBinding>
        <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"></sp:SignedParts>
        <ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy"> </ramp:RampartConfig>
      <wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>
</service>

Step 7. Deploy the service

Now we need to deploy this service in the Axis2 server. Create a service archive named SecureService.aar and drop it in to the services directory that can be found in TOMCAT_HOME/webapps/axis2/WEB-INF/services, where TOMCAT_HOME is the home of Apache Tomcat server.

Policy annotated WSDL

When a security policy is applied to a Web service, the WSDL will be annotated with that particular security policy so the client can secure the SOAP messages according to the policy defined in the WSDL. Code generators that generate Stubs to access the Web service can make use of these security polices defined in the WSDL. The policy annotated WSDL of the Web service we use for this tutorial can be found here.

Securing the Client

Step 1. Generating the Stub using WSDL2Java tool

Java2WSDL tool provided by Axis2 can be used to generate Stubs which can then be used to call Web services. Given below is the command we use in this tutorial to generate the Stub. -uri option is used to provide the URL of the WSDL, -p option is used to specify a custom package name for the generated code, -o option to specify a directory path for the generated code and -uw option to switch on un-wrapping. 

[Linux]
  $ sh WSDL2Java.sh -uri http://localhost:8080/axis2/services/SecureService?wsdl -p tutorial.rampart.client -uw  -o /project/path/
[Windows]
  $ WSDL2Java.bat -uri http://localhost:8080/axis2/services/SecureService?wsdl -p tutorial.rampart.client -uw -o /project/to/path/

Step 2. Writting the client

Now, we will write a client for the Web service using the Stub generated. Source code of the client is given below: 

package tutorial.rampart.client;

  public class SecureServiceCGClient {

    public static void main(String[] args) throws Exception {

      SecureServiceStub stub = new SecureServiceStub(null,"http://localhost:8080/axis2/services/SecureService");

      int a = 3;
      int b = 4;
      int result = stub.add(a, b);

      System.out.println(a + " + " + b + " = " + result);

    }

}

Step 3. Setting up the key store

As mentioned in "Securing the service", to sign the messages back and forth, the client also need to posses public-private key pair. In this tutorial we will be using X509 certificates for both client and the service. The client.jks which we use as the key store of the client, can downloaded with the source code of this tutorial. You can use the keytool which is shipped with Java if you want inspect the keystore and see what keys it contains.

$ keytool -v -list -keystore client.jks -storepass clientPW

Keystore type: jks
Keystore provider: SUN

Your keystore contains 2 entries

Alias name: service
Creation date: Mar 21, 2008
Entry type: trustedCertEntry

Owner: CN=service, OU=Secuirty Team, O=WSO2, L=colombo, ST=Western, C=LK, EMAILADDRESS=service@wso2.com
Issuer: CN=service, OU=Secuirty Team, O=WSO2, L=colombo, ST=Western, C=LK, EMAILADDRESS=service@wso2.com
Serial number: 47e3b6c0
Valid from: Fri Mar 21 18:53:12 LKT 2008 until: Tue Mar 15 18:53:12 LKT 2033
Certificate fingerprints:
         MD5:  C4:B9:2D:70:22:E9:08:6B:07:3B:2C:1E:5B:87:ED:09
         SHA1: 4F:C9:0C:42:01:B7:BE:AC:0D:4F:AC:00:A2:E7:CC:CA:07:40:8E:BB


*******************************************
*******************************************


Alias name: client
Creation date: Mar 21, 2008
Entry type: keyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=client, OU=Secuirty Team, O=WSO2, L=colombo, ST=Western, C=LK, EMAILADDRESS=client@wso2.com
Issuer: CN=client, OU=Secuirty Team, O=WSO2, L=colombo, ST=Western, C=LK, EMAILADDRESS=client@wso2.com
Serial number: 47e3b631
Valid from: Fri Mar 21 18:50:49 LKT 2008 until: Tue Mar 15 18:50:49 LKT 2033
Certificate fingerprints:
         MD5:  DE:66:EB:95:18:2E:44:97:05:CE:DF:FC:83:E9:53:C3
         SHA1: CE:E5:F0:BB:2F:46:A9:F0:45:60:4C:16:1B:33:FC:B5:09:0B:8C:13


*******************************************
*******************************************

As you can see, this key store contains the client's public-private key pair as a keyEntry and the service's public key as trusted certificate. Client's private key will be used to sign messages sent to the client and service's public key will be used to verify the validity of the signature in messages coming from the service.

Step 4. Writing the password callback

This is similar to the password callback class we wrote for the service. Purpose of this password callback class is to provide the password for the client’s private key. 

package tutorial.rampart.client;

import org.apache.ws.security.WSPasswordCallback;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import java.io.IOException;

public class PWCBHandler implements CallbackHandler {

    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {

        for (int i = 0; i < callbacks.length; i++) {
            
            // To use the private key to sign messages, we need to provide 
        	// the private key password 
            WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
               
            if(pwcb.getIdentifer().equals("client") ) {
            	pwcb.setPassword("clientPW");
                return;
            }
           
        }
    }

}

Step 5. Engaging Rampart

To secure SOAP requests made by the client, we need to engage the Rampart module to the client. For this, we need to create a client repository and rampart.mar should be deployed in the modules directory. We need to ensure that all dependency jar files of the Apache Rampart module is in the classpath of the client. Then the following code can be used to engage Rampart to the client: 

  // Rampart module should be in the repository 
  ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem("path/to/client/repo", null);

  SecureServiceStub stub = new SecureServiceStub(ctx,"https://localhost:8080/axis2/services/SecureService");

  ServiceClient sc = stub._getServiceClient();
  sc.engageModule("rampart");

Step 6. Setting the Rampart specific configuration details

Axis2 code generator makes use of security policies specified in the WSDL, when generating a stub for a Web service. We need to provide some Rampart specific configuration information such as which key to be used for the signature and which key store to be used. In this tutorial, we provide these information using a programmatically created RampartConfig assertion.   


  RampartConfig rampartConfig = new RampartConfig();
  rampartConfig.setUser("client");
  rampartConfig.setPwCbClass("tutorial.rampart.client.PWCBHandler");

  CryptoConfig sigCrypto = new CryptoConfig();
  sigCrypto.setProvider("org.apache.ws.security.components.crypto.Merlin");

  Properties props = new Properties();
  props.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", "JKS");
  props.setProperty("org.apache.ws.security.crypto.merlin.file","keys/client.jks");
  props.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "clientPW");

  sigCrypto.setProp(props);

  rampartConfig.setSigCryptoConfig(sigCrypto);

  Policy policy = new Policy();
  policy.addAssertion(rampartConfig);

And we can add this policy to the service client using the following code.

  Policy rampartConfig = getRampartConfig();
  sc.getAxisService().getPolicyInclude().addPolicyElement(PolicyInclude.AXIS_SERVICE_POLICY, rampartConfig);

Step 7. Calling the Web service

Now, everything is set and you can run the client and consume the Web service.

SOAP Messages Exchanged

Without security

<soapenv:Envelope>
        <soapenv:Body>
                <ns1:add xmlns:ns1="http://service.rampart.tutorial">
                        <ns1:a>4</ns1:a>
                        <ns1:b>6</ns1:b>
                </ns1:add>
        </soapenv:Body>
</soapenv:Envelope>

With Security

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
	<soapenv:Header>
        	<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="true">
			<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-13121387">
				<wsu:Created>2008-03-27T15:29:37.454Z</wsu:Created>
				<wsu:Expires>2008-03-27T15:34:37.454Z</wsu:Expires>
			</wsu:Timestamp>
			<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-29744585">
				<ds:SignedInfo>
					<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
					<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
					<ds:Reference URI="#Id-14293164">
						<ds:Transforms>
							<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
						</ds:Transforms>
						<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
						<ds:DigestValue>KELVaFQ7RnfPIUMAU9q4D/5rGOU=</ds:DigestValue>
					</ds:Reference>
					<ds:Reference URI="#Timestamp-13121387">
						<ds:Transforms>
							<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
						</ds:Transforms>
						<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
						<ds:DigestValue>7t9QUVXRJ0yTS+84OSfsH7pAguM=</ds:DigestValue>
					</ds:Reference>
				</ds:SignedInfo>
				<ds:SignatureValue> ...ZL1FMFxsUvwBU2ZYYbNxGu/uJceG1i4uSPd6+BSiqYWal ...</ds:SignatureValue>
				<ds:KeyInfo Id="KeyId-24374386">
					<wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-8406772">
						<wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" 
                                                                    ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier">
                                                        ins6410Q1skpvizn19AUk7dC6rI=
                                                </wsse:KeyIdentifier>
					</wsse:SecurityTokenReference>
				</ds:KeyInfo>
		       </ds:Signature>
	       </wsse:Security>
      </soapenv:Header>
      <soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-14293164">
      	<ns1:add xmlns:ns1="http://service.rampart.tutorial">
            <ns1:a>3</ns1:a>
            <ns1:b>4</ns1:b>
         </ns1:add>
      </soapenv:Body>
</soapenv:Envelope>

Summary

In this tutorial, we looked at deploying Apache Rampart module and applying message-level security to a Web service. We also looked at consuming a secure Web service. Even though in this example, we only  looked at a simple sign only scenario, we can sign and encrypt SOAP headers and also other parts of a message, just by changing the security policy by adding necessary protection assertions.

References

   1. Web Services Security with Apache Rampart – Part 1 (Transport Level Security)
   2. Setting Up Keystores for a Client and a Service
   3. Understanding the WS Security Policy Language

Resources

Download source code for this tutorial

Author

Nandana Mihindukulasooriya, Software Engineer, WSO2 Inc. nandana AT wso2 DOT com

mona's picture

multiple client authentication and services authorisation

I am new to web service implementation. I have tried and implemented Web services with message level security and transport level security. But now I want to implement security at three levels for my web services -- 1. Authentication of Third party (by user name and password) 3. Encryption of message by public-private key. 2. Authorization to different set of web services to different vendors(Third party users/Authenticated client applications). Can you please suggest me any of the article or pages which can guide me for this. I am confused about implementing Transport level and message level security simultaneously. I have no idea how to implement these security levels on my application. I am using axis2 for web services. Thanks in advance.
dharmendra8186.gmail.com's picture

I am getting followning errors

Hi All, When i am executing client for this tutorail I am getting bellow error. I have wss4j-1.5.1.jar file in lib folder. anyone can help me please. ava.lang.Error: Unresolved compilation problems: The import org.apache.ws.security cannot be resolved WSPasswordCallback cannot be resolved to a type WSPasswordCallback cannot be resolved to a type at tutorial.rampart.service.PWCBHandler.(PWCBHandler.java:3) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at java.lang.Class.newInstance0(Unknown Source) at java.lang.Class.newInstance(Unknown Source) at org.apache.rampart.util.RampartUtil.getPasswordCB(RampartUtil.java:144) at org.apache.rampart.util.RampartUtil.getPasswordCB(RampartUtil.java:116) at org.apache.rampart.RampartEngine.process(RampartEngine.java:130) at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.java:92) at org.apache.axis2.engine.Phase.invoke(Phase.java:317) at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:264) at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:163) at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:275) at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:133) at javax.servlet.http.HttpServlet.service(HttpServlet.java:647) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:879) at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528) at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689) at java.lang.Thread.run(Unknown Source) Thanks & Regards, Dharmendra Singh
pvanh80.gmail.com's picture

Can you help, please !!!

When I follow on all of step, my client get error like that Exception in thread "main" java.lang.NoSuchMethodError: org.apache.ws.security.message.token.Timestamp.(ZLorg/w3c/dom/Document;I)V at org.apache.ws.security.message.WSSecTimestamp.prepare(WSSecTimestamp.java:75) at org.apache.ws.security.message.WSSecTimestamp.build(WSSecTimestamp.java:113) at org.apache.rampart.builder.BindingBuilder.addTimestamp(BindingBuilder.java:90) at org.apache.rampart.builder.TransportBindingBuilder.build(TransportBindingBuilder.java:75) at org.apache.rampart.MessageBuilder.build(MessageBuilder.java:124) at org.apache.rampart.handler.RampartSender.invoke(RampartSender.java:64) at org.apache.axis2.engine.Phase.invoke(Phase.java:292) at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:212) at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:377) at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:374) at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:211) at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163) at tutorial.rampart.client.SecureServiceStub.add(SecureServiceStub.java:179) at tutorial.rampart.client.SecureServiceCGClient.main(SecureServiceCGClient.java:75) Thanks, Vietanh
edward.1.lee.lmco.com's picture

Encrypt org.apache.ws.security.crypto.merlin.keystore.password

Would it be possible to have the property field of org.apache.ws.security.crypto.merlin.keystore.password encrypted similarly to the passwordCallbackClass so the password is not hardcoded and visible in the services.xml? <ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy"> <ramp:user>service</ramp:user> <ramp:passwordCallbackClass>ServiceCallback</ramp:passwordCallbackClass> <ramp:policyValidatorCbClass>CustomPolicyBasedResultsValidator</ramp:policyValidatorCbClass> <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">service.jks</ramp:property> <ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">apache</ramp:property> </ramp:crypto> </ramp:signatureCrypto> </ramp:RampartConfig>
vishnu.iphone.gmail.com's picture

One way signature checking possible in rampart

This is answer to my own question above how to avoid signature checking in fault messages. comment out Inflow for fault in module.xml of rampart to achieve this. This could also be possible through code.
mona's picture

WS security

I am new to WS and AXIS2. I just want to know that.. if my application offers many services(say 10 services) and I want to secure my services at each service level,, which means CLIENT A can access SERVICE 1 and 4 CLIENT B can access 5 and 8 and rest of them I dont want to offer to any client for now. What kind of security should I use to implement this.
mona's picture

Getting error in executing this sample

I created webservice with message level secuirity in eclipse and deployed it on tomcat 5.5 successfully. But when I try to call that service by webservice client generated using eclipse it give error as mentioned below: org.apache.axis2.AxisFault: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430) at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:83) at org.apache.axis2.transport.http.AxisRequestEntity.writeRequest(AxisRequestEntity.java:84) at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499) at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114) at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096) at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398) at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)... Even if I generated certificate for jks file by alias name client/server and added it in cacerts but then also the error remains same. Pls help me regarding this. Thanks in advance.
emilio.alvarado.gmail.com's picture

Error invoking axis2 web service with WSSecurity

Hello.

I have followed this example and it works fine. However, i need to create a web service in axis2 using SymmetricBinding, Sign and Encryption using keys and keystores. This web service should be consumed from a .Net Client. When run the client i get this error:

ERROR An error was discovered processing the header (WSSecurityEngine: DataReference - referenced data not found) org.apache.axis2.AxisFault: An error was discovered processing the header (WSSecurityEngine: DataReference - referenced data not found) at org.apache.rampart.handler.RampartReceiver.setFaultCodeAndThrowAxisFault(RampartReceiver.java:166) at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.java:95)



My services.xml is:

<?xml version="1.0"?>
<!-- This file was auto-generated from WSDL -->
<!-- by the Apache Axis2 version: 1.4.1 Built on : Aug 13, 2008 (05:03:35 LKT) -->

<serviceGroup>
    <service name="PDIDas">
   
    <module ref="rahas" />
    <module ref="rampart" />
   
    <messageReceivers>
        <messageReceiver mep="http://www.w3.org/ns/wsdl/in-out" class="co.gov.gobiernoenlinea.www.wsentidad.PDIDasMessageReceiverInOut"/>
    </messageReceivers>
   
    <parameter name="ServiceClass">co.gov.gobiernoenlinea.www.wsentidad.PDIDasSkeleton</parameter>
    <parameter name="useOriginalwsdl">false</parameter>
    <parameter name="modifyUserWSDLPortAddress">true</parameter>
    <parameter name="enableMTOM" locked="false">true</parameter>
   
    <operation name="VerificarFuncionamiento" mep="http://www.w3.org/ns/wsdl/in-out" namespace="http://www.gobiernoenlinea.gov.co/wsentidad">
        <actionMapping>http://www.gobiernoenlinea.gov.co/wsentidad:verificarFuncionamientoIn</actionMapping>
        <outputActionMapping>http://www.gobiernoenlinea.gov.co/wsentidad/WsEntidad/VerificarFuncionamientoResponse</outputActionMapping>
    </operation>
    <operation name="Tarifar" mep="http://www.w3.org/ns/wsdl/in-out" namespace="http://www.gobiernoenlinea.gov.co/wsentidad">
        <actionMapping>http://www.gobiernoenlinea.gov.co/wsentidad:tarifarIn</actionMapping>
        <outputActionMapping>http://www.gobiernoenlinea.gov.co/wsentidad/WsEntidad/TarifarResponse</outputActionMapping>
    </operation>
    <operation name="ConsultarResultado" mep="http://www.w3.org/ns/wsdl/in-out" namespace="http://www.gobiernoenlinea.gov.co/wsentidad">
        <actionMapping>http://www.gobiernoenlinea.gov.co/wsentidad:consultarResultadoIn</actionMapping>
        <outputActionMapping>http://www.gobiernoenlinea.gov.co/wsentidad/WsEntidad/ConsultarResultadoResponse</outputActionMapping>
    </operation>
    <operation name="Ejecutar" mep="http://www.w3.org/ns/wsdl/in-out" namespace="http://www.gobiernoenlinea.gov.co/wsentidad">
        <actionMapping>http://www.gobiernoenlinea.gov.co/wsentidad:ejecutarIn</actionMapping>
        <outputActionMapping>http://www.gobiernoenlinea.gov.co/wsentidad/WsEntidad/EjecutarResponse</outputActionMapping>
    </operation>
    <operation name="Consultar" mep="http://www.w3.org/ns/wsdl/in-out" namespace="http://www.gobiernoenlinea.gov.co/wsentidad">
        <actionMapping>http://www.gobiernoenlinea.gov.co/wsentidad:consultarIn</actionMapping>
        <outputActionMapping>http://www.gobiernoenlinea.gov.co/wsentidad/WsEntidad/ConsultarResponse</outputActionMapping>
    </operation>
   
   
    <wsp:Policy
        wsu:Id="WsEntidadPolicy"
                xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
                xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
        <wsp:ExactlyOne>
            <wsp:All>
           
                <sp:SymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
               
                        <sp:ProtectionToken>
                            <wsp:Policy>
                                <sp:SecureConversationToken
                                sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                                    <wsp:Policy>
                                        <sp:BootstrapPolicy>
                                            <wsp:Policy>
                                                <sp:SymmetricBinding>
                                                    <wsp:Policy>
                                                        <sp:ProtectionToken>
                                                            <wsp:Policy>
                                                                <sp:X509Token sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Never">
                                                                    <wsp:Policy>
                                                                        <sp:WssX509V3Token10 />
                                                                    </wsp:Policy>
                                                                </sp:X509Token>
                                                            </wsp:Policy>
                                                        </sp:ProtectionToken>
                                                        <sp:Layout>
                                                            <wsp:Policy>
                                                                <sp:Lax />
                                                            </wsp:Policy>
                                                        </sp:Layout>
                                                        <sp:IncludeTimestamp/>
                                                        <sp:OnlySignEntireHeadersAndBody />
                                                        <sp:AlgorithmSuite>
                                                            <wsp:Policy>
                                                                <sp:Basic256 />
                                                            </wsp:Policy>
                                                        </sp:AlgorithmSuite>
                                                    </wsp:Policy>
                                                </sp:SymmetricBinding>
                                                <sp:EndorsingSupportingTokens>
                                                    <wsp:Policy>
                                                        <sp:X509Token
                                                            sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
                                                            <wsp:Policy>
                                                                <sp:WssX509V3Token10 />
                                                            </wsp:Policy>
                                                        </sp:X509Token>
                                                    </wsp:Policy>
                                                </sp:EndorsingSupportingTokens>
                                                <sp:Wss11>
                                                    <wsp:Policy>
                                                        <sp:MustSupportRefKeyIdentifier />
                                                        <sp:MustSupportRefIssuerSerial />
                                                        <sp:MustSupportRefThumbprint />
                                                        <sp:MustSupportRefEncryptedKey />
                                                        <sp:RequireSignatureConfirmation />
                                                    </wsp:Policy>
                                                </sp:Wss11>
                                                <sp:EncryptedParts>
                                                    <sp:Body/>
                                                </sp:EncryptedParts>
                                                <sp:SignedParts>
                                                    <sp:Body/>
                                                    <sp:Header Name="Action" Namespace="http://schemas.xmlsoap.org/ws/2004/08/addressing"/>
                                                    <sp:Header Name="RelatesTo" Namespace="http://schemas.xmlsoap.org/ws/2004/08/addressing"/>
                                                    <sp:Header Name="To" Namespace="http://schemas.xmlsoap.org/ws/2004/08/addressing"/>
                                                </sp:SignedParts>
                                            </wsp:Policy>
                                        </sp:BootstrapPolicy>
                                    </wsp:Policy>
                                </sp:SecureConversationToken>
                            </wsp:Policy>
                        </sp:ProtectionToken>
                        <sp:Layout>
                            <wsp:Policy>
                                <sp:Strict />
                            </wsp:Policy>
                        </sp:Layout>
                        <sp:AlgorithmSuite>
                            <wsp:Policy>
                                <sp:Basic256 />
                            </wsp:Policy>
                        </sp:AlgorithmSuite>
                        <sp:IncludeTimestamp />
                        <sp:OnlySignEntireHeadersAndBody />
                    </wsp:Policy>
                </sp:SymmetricBinding>
               
                <sp:Wss11 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:MustSupportRefKeyIdentifier />
                        <sp:MustSupportRefIssuerSerial />
                        <sp:MustSupportRefThumbprint />
                        <sp:MustSupportRefEncryptedKey />
                    </wsp:Policy>
                </sp:Wss11>
                <sp:Trust10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
                    <wsp:Policy>
                        <sp:RequireClientEntropy />
                        <sp:RequireServerEntropy />
                        <sp:MustSupportIssuedTokens />
                    </wsp:Policy>
                </sp:Trust10>
               
                <ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
                    <ramp:user>pdi</ramp:user>
                    <ramp:encryptionUser>www.tramitador.gov.co</ramp:encryptionUser>
                    <ramp:passwordCallbackClass>co.gov.gobiernoenlinea.www.wsentidad.PWCBHandler</ramp:passwordCallbackClass>
                   
                    <ramp:encryptionCrypto>
                        <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">keystore.jks</ramp:property>
                            <ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">adminjboss</ramp:property>
                        </ramp:crypto>
                    </ramp:encryptionCrypto>
                   
                    <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">keystore.jks</ramp:property>
                            <ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">adminjboss</ramp:property>
                        </ramp:crypto>
                    </ramp:signatureCrypto>
               
                </ramp:RampartConfig>
           
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>
   
    </service>
</serviceGroup>




I think that keystores and keys are fine, and passwordCallBackClass too.

The SOAP message is:

<soap:Envelope xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
        <wsa:Action wsu:Id="Id-d948f029-35b3-49d3-bc57-7855f36b9711">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</wsa:Action>
        <wsa:MessageID wsu:Id="Id-a29bf130-bf13-40d5-b3eb-ccbdbea0e989">urn:uuid:67edb487-6608-4663-9ec8-b09a8c2953ad</wsa:MessageID>
        <wsa:ReplyTo wsu:Id="Id-9d70df75-17c9-4d3c-8a52-3ad190abb682">
            <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
        </wsa:ReplyTo>
        <wsa:To wsu:Id="Id-000ae597-6af4-427f-947e-63f76660f9d2">http://192.168.0.177/axis2/services/PDIDas</wsa:To>
        <wsse:Security soap:mustUnderstand="1">
            <wsu:Timestamp wsu:Id="Timestamp-fbce16b7-da8c-423f-a4a2-83053d581427">
                <wsu:Created>2010-01-07T16:34:31Z</wsu:Created>
                <wsu:Expires>2010-01-07T16:39:31Z</wsu:Expires>
            </wsu:Timestamp>
            <wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-87419da6-e037-49ef-b32c-39b245ca102f">
                <xop:Include href="cid:1.633984608716794146@example.org" />
            </wsse:BinarySecurityToken>
            <xenc:EncryptedKey Id="SecurityToken-1007a64b-ac44-4a1d-b51f-070f3389e757" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
                <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
                    <ds:DigestMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                </xenc:EncryptionMethod>
                <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                    <wsse:SecurityTokenReference>
                    <wsse:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">Ry+t5evVGgJXSnljahbUQKZkJv0=</wsse:KeyIdentifier>
                    </wsse:SecurityTokenReference>
                </KeyInfo>
                <xenc:CipherData>
                    <xenc:CipherValue>eW9Sd28ycGqx3koG2wE02yHRUAyT3tuNSYdltRUBcNPD2OXuY1ZrqLnlEbv4lHLObgYvtPvdpMMxI4ReyqCKRzGfoIcxkrx9zlneegl18wQSv/AEbxLqFNiMPNix30ujKu/geDv6WB4N6MtzDckeTpPCl5OhjNXHx7+w7PQ1Tbs=</xenc:CipherValue>
                </xenc:CipherData>
                <xenc:ReferenceList>
                    <xenc:DataReference URI="#Enc-0dba6476-4323-4285-ac02-12a30aa03ce3" />
                </xenc:ReferenceList>
            </xenc:EncryptedKey>
            <Signature Id="Sig-371103f2-7cad-4c76-88e9-eb128279c9f3" xmlns="http://www.w3.org/2000/09/xmldsig#">
                <SignedInfo>
                    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
                    <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1" />
                    <Reference URI="#Id-d948f029-35b3-49d3-bc57-7855f36b9711">
                        <Transforms>
                            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                        <DigestValue>mQTnEkBe+KEz4CheppKKx2tn7OQ=</DigestValue>
                    </Reference>
                    <Reference URI="#Id-a29bf130-bf13-40d5-b3eb-ccbdbea0e989">
                        <Transforms>
                            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                        <DigestValue>9q6HeJJDPkyzb99tWJsbjbqc8IQ=</DigestValue>
                    </Reference>
                    <Reference URI="#Id-9d70df75-17c9-4d3c-8a52-3ad190abb682">
                        <Transforms>
                            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                        <DigestValue>HDEt95B0e6NLC0yb5VggvRHuIis=</DigestValue>
                    </Reference>
                    <Reference URI="#Id-000ae597-6af4-427f-947e-63f76660f9d2">
                        <Transforms>
                            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                        <DigestValue>VYVCsBhiEQg+CJ9Ftdz/tle21Tw=</DigestValue>
                    </Reference>
                    <Reference URI="#Timestamp-fbce16b7-da8c-423f-a4a2-83053d581427">
                        <Transforms>
                            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                        <DigestValue>mA+EEi1vxrvlQujV/duOX9/smo0=</DigestValue>
                    </Reference>
                    <Reference URI="#Id-ea090ef4-0050-42f5-949f-e70ff2a8e017">
                        <Transforms>
                            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                        <DigestValue>XyNjh/NfBQtfvuQE3AmEaV6T5GU=</DigestValue>
                    </Reference>
                </SignedInfo>
                <SignatureValue>V5PgwMaKwsosA72JyZOQwK+Wr98=</SignatureValue>
                <KeyInfo>
                    <wsse:SecurityTokenReference>
                    <wsse:Reference URI="#SecurityToken-1007a64b-ac44-4a1d-b51f-070f3389e757" ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey" />
                    </wsse:SecurityTokenReference>
                </KeyInfo>
            </Signature>
            <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
                <SignedInfo>
                    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
                    <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
                    <Reference URI="#Sig-371103f2-7cad-4c76-88e9-eb128279c9f3">
                        <Transforms>
                            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                        <DigestValue>V9e3jC6dYIWbZQMltjhfNZic5TA=</DigestValue>
                    </Reference>
                    </SignedInfo>
                <SignatureValue>Lqagdidn8+ZjcqvcLIWY9q7UyOEtWytfquMvkmOo7FgjG/h/ZcyjeOc/1yaKeM4TJ9nO633vweLv92z9VVd0NSkEhomj7LC6dihRobL+cK3Dg79p7ZTVMdyOrio9pTINfphFs9i2IMcipKt2hLkUs2dS9dvgkxTJsB6TXIVp7oc=</SignatureValue>
                <KeyInfo>
                    <wsse:SecurityTokenReference>
                    <wsse:Reference URI="#SecurityToken-87419da6-e037-49ef-b32c-39b245ca102f" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
                    </wsse:SecurityTokenReference>
                </KeyInfo>
            </Signature>
        </wsse:Security>
    </soap:Header>
    <soap:Body wsu:Id="Id-ea090ef4-0050-42f5-949f-e70ff2a8e017">
        <xenc:EncryptedData Id="Enc-0dba6476-4323-4285-ac02-12a30aa03ce3" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
            <xenc:CipherData>
                <xenc:CipherValue>K87I9W++OBBqgzCLi2gxXdbn6kQMjL2TcP4K5IA8BVKVTRSC5kL2XBVCSr9CR2ShgLFYMmhNQ/7vF3FkV59KkzKa+MJmOk9cHxlcgtOHwudB7ZexNbkqCHmwJkzxysV9ADMjcBEPrKMHSbb/J3EimXkX9paRFteC5Mm65DktgdxBZxC7Gi8rAbw998MhNA3jESnNhNJCR8yxduGaykkP1iaa8IZo+fb4P+LpGQIpn9kUEyM4faA8pfTaxbvDNDx/jRQL55IZOZb7279PZbiYGGKix0BYZLbX/nH2PehEDjltf4WLzRFfr8K204ja9bTy6+yFNP2gLt2Cs40armXVa15o2CCAYOV6L+9R/+c2r2faJd6ltU+GmJcRAYhMONtig2zGuhULK1DW3D3Hmd16UxY1pOU3NDCtX6hfo6JC0AECzMo8E85aN/KPMJ3DQ5/9oxZfyr1pqhzWT7g32X4SPbBnLapGN7H7brgp6R446cLi1mYn90jUf/BMHwqUlsLr+o0u68mS4dj7OVTWyRc910XAJ+fzxc6pZOsB+rNHoTZowACvaZWlX1LRPm3BikLLDKvmshrtJSwsn2KoJgYvJFypj4FuwoKymBxTtZ65KSufRl4HcCcW+Km/0LnalXwamwl+Q3KpfTfnSFcL6Q4SbWCXhQf02ELjX4QMbkrXSx6VoKrA3c4loVAq0wOs8AEAHWLlbHoPDjafEAp7ZkXoctLW+YhHFYt/YDSIQErgLZ+5VbJADaTod+66v1Ec9PdpzcZo0qYp0IlWGNzS8pW03mexNCHDeZygH3Rv9BdkTyM=</xenc:CipherValue>
            </xenc:CipherData>
        </xenc:EncryptedData>
    </soap:Body>
</soap:Envelope>


I don't know what is the problem. The client in .Net cannot be modified, it work fine, and i have applied thousand changes in service without get results.

Thanks for your help.

emilio.alvarado.gmail.com's picture

Error when datatype in service operation changes

Hi all. This tutorial work fine. But when i change the operation to return String or boolean, obviously changing the client too, i get this error: Exception in thread "main" org.apache.axis2.AxisFault: SOAP header missing public class SecureService { public int add(int a, int b) { return a+b; } } changes to: public class SecureService { public String add(int a, int b) { return new String(a + "-" + b); } } Please your comments. Thanks.
emilio.alvarado.gmail.com's picture

Problems with rampart and axis2 with specific wsdl

Hi Nandana and all. Please help me with this problem (https://wso2.org/blog/emilio-alvarado-gmail-com/8881): I need publish a web service with axis2 and rampart on tomcat, based on this wsdl and two keystores, and after generate a client to probe the service: <?xml version="1.0" encoding="UTF-8"?> -->
madhurisarkar's picture

Signature with Data encryption

Hi Nandana, It will be great if you can post a tutorial having both signature and data encryption. May be a third part of this tutorial extending the 2nd part, adding the data encryption in the policy.
madhurisarkar's picture

Response not signed

Hi Nandana, Thanks a lot for this beautiful article for layman like me :-). I followed the instructions and the srvice works for me. But I don't get a signed response. I am using Axis 14.1 and Ramprat 1.4. I have added Wss10 assertion as you mentioned: Still I get following response: <?xml version='1.0' encoding='utf-8'?> <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"> <soapenv:Body> <ns:addResponse xmlns:ns="http://service.rampart.tutorial"> <ns:return>7</ns:return> </ns:addResponse> </soapenv:Body> </soapenv:Envelope>
madhurisarkar's picture

Response not signed

Never mind: I got signed response. My bad. I used SOAPMonitor to see request/response. SOAPMonitor needs to be configured correctly to see the signed response.
vuthcam's picture

Another error

Another error :  Client [INFO] OMException in getSOAPBuilder org.apache.axiom.om.OMException: SOAP message MUST NOT contain a Document Type D eclaration(DTD)     at org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.createDTD(StAXSOAPMo delBuilder.java:407)     at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:226)     at org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.getSOAPEnvelope(StAX SOAPModelBuilder.java:156)     at org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.<init>(StAXSOAPModel Builder.java:105)     at org.apache.axis2.builder.BuilderUtil.getSOAPBuilder(BuilderUtil.java:677)     at org.apache.axis2.transport.TransportUtils.createDocumentElement(TransportUti ls.java:182)     at org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.j ava:112)     at org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.j ava:88)     at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAx isOperation.java:353)     at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperatio n.java:416)     at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisO peration.java:228)     at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)     at com.thesis.SecureServiceStub.add(SecureServiceStub.java:200)     at com.thesis.SecureServiceClient.main(SecureServiceClient.java:56) [INFO] Remaining input stream :[] Server [ERROR] org/jaxen/JaxenException java.lang.NoClassDefFoundError: org/jaxen/JaxenException     at org.apache.rampart.RampartEngine.process(RampartEngine.java:78)     at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.java:92)     at org.apache.axis2.engine.Phase.invoke(Phase.java:317)     at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:264)     at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:163)     at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HT TPTransportUtils.java:275)     at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:133)     at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)     at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Application FilterChain.java:269)     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterCh ain.java:188)     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.ja va:213)     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.ja va:172)     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127 )     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117 ) Note: on the server (service), i have included the jaxen..jar into the classpath wonder why it's still No call found ? Please help!!!
vuthcam's picture

[ERROR] SOAP header missing

I am following this article. The process was smoothly done until i run the client. Client Error : [ERROR] SOAP header missing org.apache.axis2.AxisFault: SOAP header missing     at org.apache.rampart.handler.RampartReceiver.setFaultCodeAndThrowAxisFault(Ram partReceiver.java:172)     at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.java:99)     at org.apache.axis2.engine.Phase.invoke(Phase.java:317)     at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:264)     at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:163)     at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAx isOperation.java:363)     at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperatio n.java:416)     at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisO peration.java:228)     at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)     at com.thesis.SecureServiceStub.add(SecureServiceStub.java:209)     at com.thesis.SecureServiceClient.main(SecureServiceClient.java:58) Caused by: org.apache.rampart.RampartException: SOAP header missing     at org.apache.rampart.RampartEngine.process(RampartEngine.java:99)     at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.java:92)     ... 9 more Tomcat server : [ERROR] Must Understand check failed for header http://docs.oasis-open.org/wss/2 004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd : Security org.apache.axis2.AxisFault: Must Understand check failed for header http://docs. oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd : Security     at org.apache.axis2.engine.AxisEngine.checkMustUnderstand(AxisEngine.java:102)     at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:166)     at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HT TPTransportUtils.java:275)     at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:133)     at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)     at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Application FilterChain.java:269).....   I really need help to solve this problem.. Please help me!!! Thanks in advance!! [Fixed] : By engaging Rampart module into the service
vishnu.iphone.gmail.com's picture

Did you overcome this issue

Hi Vuthcam If you have overcome this issue could you please let me know the solution for this. I have a client that sends a signed request and in response service sends a unsigned response with no security in header which is erroring out. I am using rampart 1.4 with Axis2 1.4.1 Appreciate all your help. Vishnu Deevi
vinfang's picture

How does rampart recognize what usage to set?

I'm creating a policy that has both the username password policy, and username signature, so that our web service can accept either one. So I'm following both examples from part 1 and part 2 but I'm wondering, how does rampart know what usage constant to set for the WSPasswordCallback object in the handle? Does the usage get set to signature if I create the CryptoConfig and Properties object and set it into the rampart config for the service client to use, or is there a way to explicitly set the usage? Note I'm trying to have this usage set on the client side code before it reaches the handle.
pskarthic's picture

Exception in thread "main" java.lang.NoClassDefFoundError: org/a

Err: Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/xml/utils/URI$MalformedURIException axis2 and rampart downloaded code : article message
pete's picture

missing xalan jar

org/apache/xml/utils/URI$MalformedURIException
richa's picture

Missing the namespace inside BinarySecurityToken tag

Hi, I am new to webservice but with the help of tutorial and suggestion, I manage to call the server but while its generating the security information it is not having the namespace information for xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
pete's picture

client policy file

OK, but this tutorial doesn't show how to use the policy file in a rampart client. So I looked to the sample02 in rampart for that. https://svn.apache.org/repos/asf/webservices/rampart/trunk/java/modules/rampart-samples/policy/sample02/src/org/apache/rampart/samples/policy/sample02/Client.java options.setProperty(RampartMessageData.KEY_RAMPART_POLICY, loadPolicy(args[2]));
nandanam's picture

Hi Pete,

If the service's WSDL is annotated with the policies, then when we use the codegen tool it injects the policies to the generated stub. But as you can see, the Rampart Config assertion which is a private assertion and whose sole purpose is to provide configuration information is not annotated in the WSDL. So if we are using the a code generated stub, all we have to do is create a RampartConfig assertion and attach it to the client. You can create this RampartConfig assertion programatically or you can load this from a file. If you want to load the RampartConfig from a file rather than creating programatically you should create a file containing RampartConfig assertion as the following one  <wsp:Policy wsu:Id="XSD_IPingServiceSign_policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> <wsp:ExactlyOne> <wsp:All> <ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy"> <ramp:user>client</ramp:user> <ramp:passwordCallbackClass>tutorial.rampart.client.PWCBHandler</ramp:passwordCallbackClass> <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">keys/client.jks</ramp:property> <ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">clientPW</ramp:property> </ramp:crypto> </ramp:signatureCrypto> </ramp:RampartConfig> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> and should change the getRampartConfig() of the client to load the RampartConfig from the file. private static Policy getRampartConfig(){ StAXOMBuilder builder = new StAXOMBuilder("path/to/rampartConfig.xml"); return PolicyEngine.getPolicy(builder.getDocumentElement()); } You will still attach this using Policy rampartConfig = getRampartConfig(); sc.getAxisService().getPolicyInclude().addPolicyElement(PolicyInclude.AXIS_SERVICE_POLICY, rampartConfig); What this will do is merge this assertion with the policies that are already present in the stub. But if you want to completely override the policies that are attached to the stub and you can use RampartMessageData.KEY_RAMPART_POLICY property. In that case you have to provide the complete policy with all the WS Security Policy assertions. RampartMessageData.KEY_RAMPART_POLICY always take the precedance. Options options = new Options(); options.setProperty(RampartMessageData.KEY_RAMPART_POLICY, loadPolicy("path/to/policy")); So in the earlier case, if you change the service policy as my previous comment, the WSDL generated should also have the WSS10 assertion. So if you generate the stubs against the new WSDL, the client stub will have that assetion injected to itself. So the client should work without any modifications. thanks, nandna  
pete's picture

problems with axis 1.4.1 and rampart 1.4

I'm vainly trying to follow the description above, and not only that, do it in eclipse 3.4 using the wizard generated client. I am getting stuck when I try to execute. Exception:java.lang.NullPointerException java.lang.NullPointerException at org.apache.rampart.util.RampartUtil.setKeyIdentifierType(RampartUtil.java:1141) at org.apache.rampart.builder.BindingBuilder.getSignatureBuider(BindingBuilder.java:243) at org.apache.rampart.builder.AsymmetricBindingBuilder.doSignature(AsymmetricBindingBuilder.java:626) at org.apache.rampart.builder.AsymmetricBindingBuilder.doSignBeforeEncrypt(AsymmetricBindingBuilder.java:413) at org.apache.rampart.builder.AsymmetricBindingBuilder.build(AsymmetricBindingBuilder.java:93) at org.apache.rampart.MessageBuilder.build(MessageBuilder.java:147) at org.apache.rampart.handler.RampartSender.invoke(RampartSender.java:64) at org.apache.axis2.engine.Phase.invoke(Phase.java:317) at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:264) at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:429) at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:401) at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:228) at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163) at com.my.ws.test.JmeterserviceSecStub.addition(JmeterserviceSecStub.java:240) at com.my.ws.test.TestClient.main(TestClient.java:57) I believe the code appears to want a Wss10 or Wss11 Assertion in the list of assertions on the message context. But there are none so this line causes a null pointer: public class RampartUtil ... public static void setKeyIdentifierType(RampartPolicyData rpd, WSSecBase secBase,org.apache.ws.secpolicy.model.Token token) { .... if (wss.isMustSupportRefKeyIdentifier()) { Any idea what needs to be done on the rampart config or nethi policy?
nandanam's picture

WSS10 / WSS11 Assertion

Hi Pete,     It seems that Rampart 1.4 assumes WSS10 or WSS11 to be present in the policy. This is not a mandatory requirement and we must use defaults if those assertions are not present. Please file a issue a in the Rampart JIRA so that it will be fixed in the trunk. To make this sample work with Rampart 1.4, please add  a WSS10/WSS11 assertion to the service policy. <wsp:Policy wsu:Id="SigOnly" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> <wsp:ExactlyOne> <wsp:All> <sp:AsymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"> ... </sp:AsymmetricBinding> <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"> <sp:Body/> </sp:SignedParts> <sp:Wss10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"> <wsp:Policy> <sp:MustSupportRefKeyIdentifier/> <sp:MustSupportRefIssuerSerial/> </wsp:Policy> </sp:Wss10> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> thanks,nandana
simharao's picture

assertion does not seem to help

Hello Nandana, First of all, excellent tutorial! I'm new to Axis2 and Rampart and could not have got as far without this help. Mucho thanks! I think I have taken care of everything suggested ... including the wss10/wss11 assertion, but still get the null pointer exception in RampartUtil.setKeyIdentifierType as below. Exception in thread "main" java.lang.NullPointerException  at org.apache.rampart.util.RampartUtil.setKeyIdentifierType(RampartUtil.java:1141)  at org.apache.rampart.builder.BindingBuilder.getSignatureBuider(BindingBuilder.java:243)  at org.apache.rampart.builder.AsymmetricBindingBuilder.doSignature(AsymmetricBindingBuilder.java:626)  at org.apache.rampart.builder.AsymmetricBindingBuilder.doSignBeforeEncrypt(AsymmetricBindingBuilder.java:413)  at org.apache.rampart.builder.AsymmetricBindingBuilder.build(AsymmetricBindingBuilder.java:93)  at org.apache.rampart.MessageBuilder.build(MessageBuilder.java:147)  at org.apache.rampart.handler.RampartSender.invoke(RampartSender.java:64)  at org.apache.axis2.engine.Phase.invoke(Phase.java:317)  at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:264)  at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:429)  at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:401)  at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:228)  at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)  at tutorial.rampart.client.AnotherSecureServiceStub.add(AnotherSecureServiceStub.java:193)  at tutorial.rampart.client.AnotherSecureServiceCGClient.main(AnotherSecureServiceCGClient.java:38)   Could there be any other causes for this? Any advise would be great.  BTW, my "AnotherSecureService*.java" are so named because I didn't want to lose track of what was done on the TLS tutorial. Thanks. Cheers! -SR
pete's picture

Jira incident

https://issues.apache.org/jira/browse/RAMPART-198
bthor's picture

changes for 1.4?

Would it be possible to get this tutorial updated for the latest version? I'm having a lot of problems getting the client to work correctly... just the raw source would be great.
nandanam's picture

Re: changes for 1.4?

Are you trying the sample with Axis2 1.4.1 and Rampart 1.4 ? Please add the WSS10/WSS11 assertions as instructed in my other comment. And if you come across any problems please feel free to post them here and I will look in to them. Thanks for the feedback. regards, nandana
moni_sparkle.yahoo.com's picture

org.apache.axis2.AxisFault: Remote host closed connection during

The client code for Axis 2.1.5.1 and Rampart 1.4 cannot use stub, but should use the service client class to invoke the webservice. I modified it to the following: package tutorial.rampart.client; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; import org.apache.axis2.description.PolicyInclude; import org.apache.neethi.Policy; import org.apache.rampart.policy.model.CryptoConfig; import org.apache.rampart.policy.model.RampartConfig; import java.util.Properties; /** * Created by IntelliJ IDEA. * User: mxshah * Date: Apr 8, 2010 * Time: 12:10:43 PM * To change this template use File | Settings | File Templates. */ public class SecureServiceCGClient { public static void main(String[] args) throws Exception { // Rampart module should be in the repository ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem("C:\\IdeaProjects\\SecureService\\repo", null); SecureServiceStub stub = new SecureServiceStub(ctx,"https://localhost:8080/axis2/services/SecureService"); ServiceClient sc = stub._getServiceClient(); sc.engageModule("rampart"); Policy rampartConfig = getRampartConfig(); sc.getAxisService().getPolicyInclude().addPolicyElement(PolicyInclude.AXIS_SERVICE_POLICY, rampartConfig); OMElement response = sc.sendReceive(getPayload("3", "4")); System.out.println(response); // SecureServiceStub stub = new SecureServiceStub(null,"http://localhost:8080/axis2/services/SecureService"); /* int a = 3; int b = 4; int result = stub.add(a, b); System.out.println(a + " + " + b + " = " + result); */ } private static OMElement getPayload(String value, String value1) { OMFactory factory = OMAbstractFactory.getOMFactory(); OMNamespace ns = factory.createOMNamespace("http://tutorial.rampart.client.apache.org","ns1"); OMElement elem = factory.createOMElement("add", ns); OMElement childElem = factory.createOMElement("param0", null); childElem.setText(value); elem.addChild(childElem); OMElement childElem1 = factory.createOMElement("param1", null); childElem.setText(value1); elem.addChild(childElem1); return elem; } private static Policy getRampartConfig() { RampartConfig rampartConfig = new RampartConfig(); rampartConfig.setUser("client"); rampartConfig.setPwCbClass("tutorial.rampart.client.PWCBHandler"); CryptoConfig sigCrypto = new CryptoConfig(); sigCrypto.setProvider("org.apache.ws.security.components.crypto.Merlin"); Properties props = new Properties(); props.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", "JKS"); props.setProperty("org.apache.ws.security.crypto.merlin.file","C:\\WebServiceSecurity\\certs\\client.jks"); props.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "changeme"); sigCrypto.setProp(props); rampartConfig.setSigCryptoConfig(sigCrypto); Policy policy = new Policy(); policy.addAssertion(rampartConfig); return policy; } } I get the following error: Exception in thread "main" org.apache.axis2.AxisFault: Remote host closed connection during handshake at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430) at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:83) at org.apache.axis2.transport.http.AxisRequestEntity.writeRequest(AxisRequestEntity.java:84) at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499) at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114) at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096) at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398) at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:346) at org.apache.axis2.transport.http.AbstractHTTPSender.executeMethod(AbstractHTTPSender.java:542) at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:199) at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:76) at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:400) at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:225) at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:435) at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:402) at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229) at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165) at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:540) at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:521) at tutorial.rampart.client.SecureServiceCGClient.main(SecureServiceCGClient.java:37) Caused by: com.ctc.wstx.exc.WstxIOException: Remote host closed connection during handshake at com.ctc.wstx.sw.BaseStreamWriter.flush(BaseStreamWriter.java:313) at org.apache.axiom.om.impl.MTOMXMLStreamWriter.flush(MTOMXMLStreamWriter.java:168) at org.apache.axiom.om.impl.dom.NodeImpl.serializeAndConsume(NodeImpl.java:830) at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:79) ... 20 more Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:808) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1120) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623) at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123) at java.io.FilterOutputStream.flush(FilterOutputStream.java:123) at org.apache.commons.httpclient.ChunkedOutputStream.flush(ChunkedOutputStream.java:191) at com.ctc.wstx.io.UTF8Writer.flush(UTF8Writer.java:99) at com.ctc.wstx.sw.BufferingXmlWriter.flush(BufferingXmlWriter.java:214) at com.ctc.wstx.sw.BaseStreamWriter.flush(BaseStreamWriter.java:311) ... 23 more Caused by: java.io.EOFException: SSL peer shut down incorrectly at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:333) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:789) ... 33 more Any tips on resolving this will be much appreciated. I created the certs / keys based on the following tutorial from Ruchith: http://wso2.org/library/174 I have tried again and again and have been looking for possible solutions for the last week but in vain. Any tips on resolving this will be helpful. Best wishes, Monsiha
moni_sparkle.yahoo.com's picture

org.apache.axis2.AxisFault: Remote host closed connection during

The client code for Axis 2.1.5.1 and Rampart 1.4 cannot use stub, but should use the service client class to invoke the webservice. I modified it to the following: package tutorial.rampart.client; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; import org.apache.axis2.description.PolicyInclude; import org.apache.neethi.Policy; import org.apache.rampart.policy.model.CryptoConfig; import org.apache.rampart.policy.model.RampartConfig; import java.util.Properties; /** * Created by IntelliJ IDEA. * User: mxshah * Date: Apr 8, 2010 * Time: 12:10:43 PM * To change this template use File | Settings | File Templates. */ public class SecureServiceCGClient { public static void main(String[] args) throws Exception { // Rampart module should be in the repository ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem("C:\\IdeaProjects\\SecureService\\repo", null); SecureServiceStub stub = new SecureServiceStub(ctx,"https://localhost:8080/axis2/services/SecureService"); ServiceClient sc = stub._getServiceClient(); sc.engageModule("rampart"); Policy rampartConfig = getRampartConfig(); sc.getAxisService().getPolicyInclude().addPolicyElement(PolicyInclude.AXIS_SERVICE_POLICY, rampartConfig); OMElement response = sc.sendReceive(getPayload("3", "4")); System.out.println(response); // SecureServiceStub stub = new SecureServiceStub(null,"http://localhost:8080/axis2/services/SecureService"); /* int a = 3; int b = 4; int result = stub.add(a, b); System.out.println(a + " + " + b + " = " + result); */ } private static OMElement getPayload(String value, String value1) { OMFactory factory = OMAbstractFactory.getOMFactory(); OMNamespace ns = factory.createOMNamespace("http://tutorial.rampart.client.apache.org","ns1"); OMElement elem = factory.createOMElement("add", ns); OMElement childElem = factory.createOMElement("param0", null); childElem.setText(value); elem.addChild(childElem); OMElement childElem1 = factory.createOMElement("param1", null); childElem.setText(value1); elem.addChild(childElem1); return elem; } private static Policy getRampartConfig() { RampartConfig rampartConfig = new RampartConfig(); rampartConfig.setUser("client"); rampartConfig.setPwCbClass("tutorial.rampart.client.PWCBHandler"); CryptoConfig sigCrypto = new CryptoConfig(); sigCrypto.setProvider("org.apache.ws.security.components.crypto.Merlin"); Properties props = new Properties(); props.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", "JKS"); props.setProperty("org.apache.ws.security.crypto.merlin.file","C:\\WebServiceSecurity\\certs\\client.jks"); props.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "changeme"); sigCrypto.setProp(props); rampartConfig.setSigCryptoConfig(sigCrypto); Policy policy = new Policy(); policy.addAssertion(rampartConfig); return policy; } } I get the following error: Exception in thread "main" org.apache.axis2.AxisFault: Remote host closed connection during handshake at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430) at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:83) at org.apache.axis2.transport.http.AxisRequestEntity.writeRequest(AxisRequestEntity.java:84) at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499) at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114) at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096) at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398) at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:346) at org.apache.axis2.transport.http.AbstractHTTPSender.executeMethod(AbstractHTTPSender.java:542) at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:199) at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:76) at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:400) at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:225) at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:435) at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:402) at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229) at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165) at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:540) at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:521) at tutorial.rampart.client.SecureServiceCGClient.main(SecureServiceCGClient.java:37) Caused by: com.ctc.wstx.exc.WstxIOException: Remote host closed connection during handshake at com.ctc.wstx.sw.BaseStreamWriter.flush(BaseStreamWriter.java:313) at org.apache.axiom.om.impl.MTOMXMLStreamWriter.flush(MTOMXMLStreamWriter.java:168) at org.apache.axiom.om.impl.dom.NodeImpl.serializeAndConsume(NodeImpl.java:830) at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:79) ... 20 more Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:808) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1120) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623) at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123) at java.io.FilterOutputStream.flush(FilterOutputStream.java:123) at org.apache.commons.httpclient.ChunkedOutputStream.flush(ChunkedOutputStream.java:191) at com.ctc.wstx.io.UTF8Writer.flush(UTF8Writer.java:99) at com.ctc.wstx.sw.BufferingXmlWriter.flush(BufferingXmlWriter.java:214) at com.ctc.wstx.sw.BaseStreamWriter.flush(BaseStreamWriter.java:311) ... 23 more Caused by: java.io.EOFException: SSL peer shut down incorrectly at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:333) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:789) ... 33 more Any tips on resolving this will be much appreciated. I created the certs / keys based on the following tutorial from Ruchith: http://wso2.org/library/174 I have tried again and again and have been looking for possible solutions for the last week but in vain. Any tips on resolving this will be helpful. Best wishes, Monsiha
library project main code
Learn Cloud
Learn
Cloud

The WSO2 Application Server is a reliable application server that can host your enterprise web applications. The WSO2 Application Server as a Service is offered in StratosLive, the WSO2 Platform as a Service. This article explains how a simple web application can be developed and deployed from Carbon Studio to the WSO2 Application Server...

Latest Webinar
Different groups within an organization need to monitor different Key Performance Indicators (KPIs) - An operations team will be interested in the response times of business services and loads of each service,..
Thursday, February 9th 2012, 09.00 AM (PST)

Thursday, February 9th 2012, 10.00 AM (GMT)