Extracting SAML assertions from a proxy service and adding them back to the service behind

This blog post explains how to do the intial setup with WSO2 ESB and the Identity Server to develop claim aware web services - please go through it first.

There - we get the SAML Assertion to the proxy service.

Here what we are going to do is - to extract SAML Assertions from the Security header of the incoming message and add those as a custom header to the message going to the actual service.

First, please download the org.wso2.carbon.identity.samples.saml.mediator-2.0.0.SNAPSHOT.jar from here.

Stop - the ESB if it's running already.

Copy the above jar to [ESB_HOME]\webapps\ROOT\WEB-INF\plugins\console.

Open [ESB_HOME]\webapps\ROOT\WEB-INF\eclipse\configuration\org.eclipse.equinox.simpleconfigurator\bundles.info and add the following entry to the end [one line].

org.wso2.carbon.identity.samples.saml.mediator,2.0.0.SNAPSHOT,file:plugins/org.wso2.carbon.identity.samples.saml.mediator-2.0.0.SNAPSHOT.jar,10,true

Start the ESB with following.

\> wso2server.bat -cleanCache

Now, you need to add the above mediator to the in sequence of your proxy service as a Class mediator.

Following is the synapase configuration for the in/out sequences of the proxy service.

<syn:proxy name="test" transports="https http" startOnLoad="true" trace="disable">
  <syn:target>
    <syn:inSequence>
      <syn:class name="org.wso2.carbon.identity.samples.saml.mediator.SAMLAttrMediator"/>
      <syn:header xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" name="wsse:Security" action="remove"/>
      <syn:log level="full"/>
      <syn:send/>
    </syn:inSequence>
    <syn:outSequence>
      <syn:send/>
    </syn:outSequence>
  </syn:target>
</syn:proxy>
You can clearly see Class/Header/Log & Send mediators are in the in-sequence and Send mediator in the out-sequence.

Now - the question is how do we capture the SAML attributes from the actual service.

You can call the following method from any service method to get the attributes in a HashMap.

getAttributes(MessageContext.getCurrentMessageContext());

Following is the code for getAttributes() method.

private static final String USER_ATTRIBUTES_ELEMENT = "UserAttributes";
private static final String USER_ATTRIBUTES_NS = "http://attributes.saml.axis2.org";
private static final String ATTRIBUTE = "Attribute";
private static final String ATTRIBUTE_NS = "AttributeNamespace";
private static final String ATTRIBUTE_VALUE = "AttributeValue";
public final static String SAML10_NS = "urn:oasis:names:tc:SAML:1.0:assertion";
public final static String SAML11_NS = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1";
public final static String SAML20_NS = "urn:oasis:names:tc:SAML:2.0:assertion";

public Map getAttributes(MessageContext messageContext) {
OMElement header = null;
OMElement userAttr = null;
Iterator iterator = null;
String samlNameSpace = null;

header = messageContext.getEnvelope().getHeader();
userAttr = header.getFirstChildWithName(new QName(USER_ATTRIBUTES_NS,
USER_ATTRIBUTES_ELEMENT));
iterator = userAttr.getChildrenWithName(new QName(SAML10_NS, ATTRIBUTE));

if (iterator.hasNext()) {
samlNameSpace = SAML10_NS;
} else {
iterator = userAttr.getChildrenWithName(new QName(SAML11_NS, ATTRIBUTE));
if (iterator.hasNext()) {
samlNameSpace = SAML11_NS;
} else {
iterator = userAttr.getChildrenWithName(new QName(SAML20_NS, ATTRIBUTE));
if (iterator.hasNext()) {
samlNameSpace = SAML20_NS;
}
}
}

if (samlNameSpace == null) {
// Unsupported SAML token type;
return null;
}

Map attributes;
attributes = new HashMap();

while (iterator.hasNext()) {
OMElement attr = iterator.next();
OMElement attrValElement = null;
String attributeName = null;
String attributeValue = null;
attributeName = attr.getAttributeValue(new QName(ATTRIBUTE_NS));
attrValElement = attr.getFirstChildWithName(new QName(samlNameSpace, ATTRIBUTE_VALUE));
attributeValue = attrValElement.getText();
attributes.put(attributeName, attributeValue);
}

return attributes;
}
Also make sure you import following packages as well.

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.namespace.QName;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.context.MessageContext;