Thursday, May 28, 2009

Adding fine-grained authorization for proxy services in WSO2 ESB

With the latest WSO2 ESB - you can add fine-grained authorization with XACML, to proxy services - with the Entitlement mediator.

First you need to configure the WSO2 Identity Server 2.0 as the XACML engine and this explains how to do it.

WSO2 Identity Server 2.0 is a free and open source identity and entitlement management server, available to download from here...

Now, let's see how we can configure Entitlement mediator in the WSO2 ESB.

First, we are creating a proxy service going through the following wizard.

Under In Sequence- we are creating an Anonymous sequence - to include Entitlement,Header and Send mediators.

First let's add Advanced/Entitlement Mediator - to the InSequence.

Here, the Entitlement Server should be the endpoint from the Identity Server 2.0, where entitlement engine is running [https://[IDENTITY_SERVER]:[PORT]/services/].

And, the user we set there, should have login and manage configuration permissions in the Identity Server.

Now, let's add the Transform/Header mediator.

There you need to remove the 'Security' header. Click on the Namespaces link to set the wsse namespace.

Prefif : wsse

Now, add a Core/Send mediator and save to return to the main flow.

Add a Core/Send mediator to the Out Sequence as an Anonymous sequence and save to return to the main flow - and complete creating the proxy service.

Now, we need to apply UsernameToken security policy to the proxy service we just created. This explains how to do it.

Here - we have a slight issue, since the security policy being applied to the binding by the policy editor - this has an issue with proxy services.

To overcome this, from the service listing, select the proxy service and then select 'Policies' - there remove the applied policies from the Binding Hierarchy and add that policy to the Service Hierarchy.

That's it - and all done - we are ready with the proxy service.

Now - we need to write a client to invoke the secured proxy service.

The following client tries to invoke the echo service deployed in ESB - through the proxy service we just created.

import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.neethi.Policy;
import org.apache.neethi.PolicyEngine;
import org.apache.rampart.RampartMessageData;

public class TestClient {

final static String ADDR_URL = "";
final static String TRANS_URL = ""; 

public static void main(String[] args) throws Exception {
ServiceClient client = null;
Options options = null;
OMElement response = null;
ConfigurationContext context = null;
String trustStore = null;

// You need to import the ESBs public certificate to this key store.
trustStore = "mykeystore.jks";
// We are accessing ESB over HTTPS - so need to set trustStore parameters.
System.setProperty("", trustStore);
// Password of mykeystore.jks
System.setProperty("", "wso2carbon");

// Create configuration context - you will have Rampart module engaged in the client.axis2.xml
context = ConfigurationContextFactory.createConfigurationContextFromFileSystem("repo","repo/conf/client.axis2.xml");

// This is the security policy of the proxy service applied UT.
StAXOMBuilder builder = new StAXOMBuilder("policy.xml");
Policy policy = PolicyEngine.getPolicy(builder.getDocumentElement());

context = ConfigurationContextFactory.createConfigurationContextFromFileSystem("repo","repo/conf/client.axis2.xml");
client = new ServiceClient(context, null);
options = new Options();
// This is the addressing URL pointing to the echo service deployed in ESB
options.setTo(new EndpointReference(ADDR_URL));
// To the ESB, the proxy service
// TRANS_URL points to proxy service
options.setProperty(Constants.Configuration.TRANSPORT_URL, TRANS_URL);
options.setProperty(RampartMessageData.KEY_RAMPART_POLICY, policy);
response = client.sendReceive(getPayload("Hello world"));

private static OMElement getPayload(String value) {
OMFactory factory = null;
OMNamespace ns = null;
OMElement elem = null;
OMElement childElem = null;

factory = OMAbstractFactory.getOMFactory();
ns = factory.createOMNamespace("", "ns1");
elem = factory.createOMElement("echoString", ns);
childElem = factory.createOMElement("in", null);
return elem;