WSF/Spring, Axis2 + Spring Security with WS-Signature

Hi, I want to comment my experience on setting up a web service using WSF/Spring to expose and axis2 web service and integrating this with Spring Security so the authentication gets done by spring.

I will asume you have already set up a web service with WSF/Spring (just WSF for brevity) + WS-Signature (using rampart) and that you know about spring security, I will only show how to add an axis2 handler to WSF to intercept incoming web services operations and authenticate them using spring security and WS-Signature.

Axis2 Handler for Spring Security Integration



import util.ServiceContext;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.engine.Handler;
import org.apache.axis2.handlers.AbstractHandler;
import org.apache.ws.security.WSSecurityEngineResult;
import org.apache.ws.security.handler.WSHandlerConstants;
import org.apache.ws.security.handler.WSHandlerResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

import javax.security.auth.Subject;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.List;

/**
* Executed in a custom phase after the security phase has been proccesed
*
* Creado por: jaime
* 28/12/11
*/
public class SpringSecurityHandler extends AbstractHandler {

@Override
public InvocationResponse invoke(MessageContext msgContext) throws AxisFault {


//  get xmldsig and authenticate
List<Object> results = (List<Object>) msgContext.getProperty(WSHandlerConstants.RECV_RESULTS);
if (results == null) {
return InvocationResponse.ABORT;
}


for (Iterator iter = results.iterator(); iter.hasNext(); ) {
WSHandlerResult hr = (WSHandlerResult) iter.next();
if (hr == null || hr.getResults() == null) {
return InvocationResponse.ABORT;
}
for (Iterator it = hr.getResults().iterator(); it.hasNext(); ) {
WSSecurityEngineResult er = (WSSecurityEngineResult) it.next();
if (er != null && er.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE) instanceof X509Certificate) {
X509Certificate x509Cert= (X509Certificate) er.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);

// TODO check against database

SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(x509Cert, null));


return InvocationResponse.CONTINUE;
}
}
}
return InvocationResponse.ABORT;
}

}

 

axis2Config.xml (Displaying only modified parts)


<bean id="axis2InFaultPhaseOrder">
<property name="phaseOrderType" value="InFaultFlow"></property>
<property name="phases">
<list>
<ref bean="axis2AddressingPhase"/>
<ref bean="security"/>
<ref bean="springSecurityCheckPhase"/>
<ref bean="preDispatchPhase"/>
<bean id="InFaultDispatchPhase">
<property name="name" value="Dispatch"></property>
<property name="clazz" value="org.apache.axis2.engine.DispatchPhase"></property>
<property name="handlers">
<list>
<ref bean="RequestURI"/>
<ref bean="SOAPAction"/>
<ref bean="RequestURIOperation"/>
<ref bean="SOAPMessageBody"/>
<ref bean="HTTPLocationBased"/>
</list>
</property>
</bean>
</list>
</property>
</bean>

<bean id="axis2InPhaseOrder">
<property name="phaseOrderType" value="InFlow"></property>
<property name="phases">
<list>
<ref bean="axis2TransportPhase"/>
<ref bean="axis2AddressingPhase"/>
<ref bean="security"/>
<ref bean="springSecurityCheckPhase"/>
<ref bean="preDispatchPhase"/>
<bean id="InDispatchPhase">
<property name="name" value="Dispatch"></property>
<property name="clazz" value="org.apache.axis2.engine.DispatchPhase"></property>
<property name="handlers">
<list>
<ref bean="RequestURI"/>
<ref bean="SOAPAction"/>
<ref bean="RequestURIOperation"/>
<ref bean="SOAPMessageBody"/>
<ref bean="HTTPLocationBased"/>
</list>
</property>
</bean>

</list>
</property>
</bean>



....

<!-- add a handler in the Security phase after SecurityInHandler-->

<bean id="springSecurityHandlerBean">
<property name="name" value="SpringSecurityHandler"></property>
<property name="clazz" value="com.kprtech.service.ws.security.SpringSecurityHandler"></property>
</bean>

<bean id="springSecurityCheckPhase">
<property name="name" value="SpringSecurityCheckPhase" />
<property name="handlers">
<list>
<ref bean="springSecurityHandlerBean"/>
</list>
</property>
</bean>


The last part of xml is creating a new phase with a handler (SpringSecurityHandler) and attaching it to axis2InPhaseOrder and axis2InFaultPhaseOrder after the Security proccesing of rampart.

4 thoughts on “WSF/Spring, Axis2 + Spring Security with WS-Signature”

  1. Hola Jamie,

    quisiera saber si encontraste una solucion para el problem que estavas teniendo con WS-Security wso2
    /usr/sbin/apache2: symbol lookup error: /usr/lib/php5/xxx/wsf.so: undefined symbol: rampart_context_create
    Ami me esta pasando lo mismo.
    Gracias

    I’d like to know if you found a solution to the issue you were having with WS-Security wso2. I’m running into the same issue.
    /usr/sbin/apache2: symbol lookup error: /usr/lib/php5/xxx/wsf.so: undefined symbol: rampart_context_create

    Thanks.

  2. Hi, in that machine I didn´t found a solution but I’m almost sure it was because of the ubuntu desktop installation (11.10) result of an update from a version 10.x.

    But I did get it working in a clean installation of Ubuntu 11.04 server with

    httpd-2.2.6.tar.gz
    php-5.3.8.tar.bz2
    wso2-wsf-php-src-2.1.0.zip

    All compiled from source.

    What are the details about your platform?

  3. No problem.

    I have two working installations of wsf 2.1.0 and the both are running in Ubuntu 11.04, one desktop and the other is a server version, one with apache and php compiled from sources and the other with these got from apt-get. The problem with

    undefined symbol: rampart_context_create

    did only happened with 11.10 version of ubuntu Desktop. Maybe this version uses some kind of imcompatible libraries that are getting apache confused.

Leave a Reply

Your email address will not be published. Required fields are marked *