Pages

Sunday, September 21, 2014

ESB: Invoking secured backend - Part 2 - Username Token - Dynamic username

My previous post shows how to invoke an username token secured backend using an ESB proxy. But we used static value for the username ( tom ), which is hard coded in the policy file. So each request authenticated as tom at the backend service.

But some may wants to access backend service as different users. This post discusses how you can extend it to support dynamic user name in policy file.


Setting up environment : 

Setup both WSO2 AS and WSO2 ESB as mentioned in previous post. 


ClassMediator (ESB)
  • In this scenario, we set username as a property in the ESB proxy. 
  • To pass username into RampartConfiguration, we use custom class mediator called, SetUserMediator.
  • This custom mediator, adds username into rampartConfigCallbackProperties map and set the map into Axis2MessageContext. So later we can access these properties from Rampart ConfigCallbackHandlers. 
  • We have to use customMediator, since we can't set a Map using standard ESB mediators.  
  • ( Maven Project is located here. )
package org.example.rampart.mediator;
import java.util.Hashtable;
import java.util.Map;
import org.apache.synapse.Mediator;
import org.apache.synapse.MessageContext;
import org.apache.synapse.core.axis2.Axis2MessageContext;
public class SetUserMediator implements Mediator {
private String username;
@Override
public boolean mediate(MessageContext synCtx) {
org.apache.axis2.context.MessageContext msgContext = ((Axis2MessageContext) synCtx)
.getAxis2MessageContext();
Map<String, String> rampConfigCBProperties = new Hashtable<String, String>();
System.out.println("Setting username to rampartConfigCallbackProperties: " + getUsername());
rampConfigCBProperties.put("user_name", getUsername());
msgContext.setProperty("rampartConfigCallbackProperties",
rampConfigCBProperties);
return true;
}
public String getUsername() {
if (username == null) {
username = "";
}
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String getDescription() {return null;}
@Override
public void setDescription(String arg0) {}
@Override
public int getMediatorPosition() {return 0; }
@Override
public String getShortDescription() {return null; }
@Override
public int getTraceState() {return 0; }
@Override
public String getType() {return null; }
@Override
public boolean isContentAware() {return false; }
@Override
public void setMediatorPosition(int arg0) {}
@Override
public void setShortDescription(String arg0) {}
@Override
public void setTraceState(int arg0) {}
}


Rampart ConfigCallbackHandler (ESB)
  • Similar to PasswordCallback handler, Rampart provides Configuration Callback handler to dynamically load Rampart configuaraion to runtime. We use this to set username dynamically. 
  • ( Maven Project is located here. )

package org.example.rampart;
import java.util.Map;
import org.apache.rampart.RampartConfigCallbackHandler;
import org.apache.rampart.policy.model.RampartConfig;
public class UTConfigCallbackHandler implements RampartConfigCallbackHandler{
@Override
public void update(RampartConfig rampartConfig) {
Map<String, String> propertyMap = rampartConfig.getPropertyMap();
if (propertyMap != null && propertyMap.containsKey("user_name")) {
System.out.println("Updating UT user name dynamically : " + propertyMap.get("user_name"));
rampartConfig.setUser(propertyMap.get("user_name"));
}
rampartConfig.setPwCbClass("org.example.rampart.PWCBHandler");
}
}

Policy for UsernameToken  ( ESB )
  • Create an ESB in-line xml local entry called "UTOverTransportDynamic.xml" with following content. 

<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UTOverTransport">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false"></sp:HttpsToken>
</wsp:Policy>
</sp:TransportToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256></sp:Basic256>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Lax></sp:Lax>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp></sp:IncludeTimestamp>
</wsp:Policy>
</sp:TransportBinding>
<sp:SignedSupportingTokens 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"></sp:UsernameToken>
</wsp:Policy>
</sp:SignedSupportingTokens>
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:rampartConfigCallbackClass>org.example.rampart.UTConfigCallbackHandler</ramp:rampartConfigCallbackClass>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>

Proxy Service (ESB)

  • Create a proxy called EchoUTDynamicProxy with following content. 
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="EchoUTDynamicProxy"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<log level="full"/>
<class name="org.example.rampart.mediator.SetUserMediator">
<property name="username" value="bob"/>
</class>
<send>
<endpoint>
<address uri="https://localhost:9443/services/echo">
<enableSec policy="UTOverTransportDynamic.xml"/>
</address>
</endpoint>
</send>
</inSequence>
<outSequence>
<log level="full"/>
<header xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
name="wsse:Security"
scope="default"
action="remove"/>
<send/>
</outSequence>
</target>
<publishWSDL uri="http://localhost:9763/services/echo?wsdl"/>
<description/>
</proxy>

Testing Scenario

  • Enable Soap tracer on WSO2 AS.
  • Invoke EchoUTDynamicProxy  using SOAP UI. 
You can see Username token in request message as follows.


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:echo="http://echo.services.core.carbon.wso2.org">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-7">
<wsu:Created>2014-09-21T06:38:53.795Z</wsu:Created>
<wsu:Expires>2014-09-21T06:43:53.795Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-8">
<wsse:Username>bob</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bobpass</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<echo:echoString>
<!--Optional:-->
<in>?</in>
</echo:echoString>
</soapenv:Body>
</soapenv:Envelope>
view raw gistfile1.xml hosted with ❤ by GitHub

No comments:

Post a Comment