Saturday, November 15, 2008

Security Policy with Rampart - UserNameToken

This post explains security policy basics with an example in Rampart.

Here the service expects clients to authenticate themselves with username/password credentials.

Usually non-functional descriptions and QoS aspects are covered by WS-Policy - and assertions related to security are covered under WS-SecurityPolicy.

You can read more about WS-SecurityPolicy from here.

Let's see how the above requirements being expressed in service policy.

<service name="SimpleService">
<module ref="rampart" />

<operation name="echo">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</operation>

<parameter name="ServiceClass" locked="false">org.apache.ws.axis2.SimpleService/>

<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:SupportingTokens
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"/>
</wsp:Policy>
</sp:SupportingTokens>

<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:passwordCallbackClassvorg.apache.ws.axis2.PWCBHandler</ramp:passwordCallbackClass>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</service>
Lets start with the most inner part.

<wsp:Policy>
<sp:UsernameToken
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"/>
</wsp:Policy>
The above requests to include username/password credentials in all the messages sent from initiator to recipient.

<sp:SupportingTokens
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
</sp:SupportingTokens>
Supporting tokens are included in the security header and in our case UsernameToken will be expected in the header.

<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:passwordCallbackClass>org.apache.ws.axis2.PWCBHandler</ramp:passwordCallbackClass>
</ramp:RampartConfig>
This is not policy specific - but Rampart specific - it simply says Rampart to where to find the password callback class at the service end to verify client credentials.

That's it with policy, you need to write the service class and the password callback handler for the service. This may help you in doing that.

Now, lets look at the client.

Use wsdl2java tool to generate service stubs.

wsdl2java -uri http://localhost:8080/axis2/services/SimpleService?wsdl -ns2p http://axis2.ws.apache.org=org.apache.ws.axis2 -uw

package org.apache.ws.axis2;

import java.rmi.RemoteException;

import org.apache.axis2.client.Options;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;

public class Client {

private static final String SERVICE_EPR = "http://localhost:8080/axis2/services/SimpleService";

public static void main(String[] args) throws RemoteException {
SimpleServiceStub service = null;
Options options = null;
ConfigurationContext configContext = null;

configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem("repo", null);

service = new SimpleServiceStub(configContext, SERVICE_EPR);

// engage rampart module
service._getServiceClient().engageModule("rampart");

options = service._getServiceClient().getOptions();
// add username/password credentials
options.setUserName("bob");
options.setPassword("bobPW");

System.out.println(service.echo("Hi"));
}
}

2 comments:

Prezesik said...

I have tried your solution but I get org.apache.axis2.AxisFault: UsernameToken missing in request exception every time I've made a request.

faisal sk said...

Hi,
I have requirement bit different i get normal header request with username&password need to validate with wso2 esb user-store like username-token done.But username-token has its own message format where as my client is not sending me in that format how would i change header before the proxy.
please refer this
http://stackoverflow.com/questions/24177794/how-to-write-custom-handler-axis2-handler-to-read-custom-headers-message-and-v