Category Archives: spring

CXF WS-Security using JSR 181 + Interceptor Annotations (XFire Migration)

I had blogged about how to setup XFire with WS-Security a while ago and since then the XFire 1.x series as we know it is dead, instead Apache’s CXF can be considered XFire 2.0. CXF improves over XFire in many areas including better architecture and more importantly easier message handling and manipulation. In this entry, we’ll setup a CXF application that secures its services using CXF’s WS-Security features.

Before I get to the example I want to mention some of the major changes that I noticed in CXF:

  • Interceptors instead of handlers: Handlers are out and are replaced with a much more common concept of interceptors (if you’re from the Struts2/Webwork world you know what they are). Interceptors are created by extending the AbstractPhaseInterceptor class which forces you to implement handleMessage(Message). Note that you must specify the phase where you want each interceptor executed.
  • Access to MessageContext: In XFire, the MessageContext was always available in your handlers. In CXF you don’t have access to it in the interceptor but you can get contextual properties using the message.getContextualProperty(String) methods. Access to the MessageContext is also available using the @Resource annotation as described here but this only works in service implementations.
  • JAXWS Endpoints: Spring service classes must be exposed using the <jaxws:endpoint> tag. You can also do this programmatically but why would you.
  • Message and Exchange: The Message and Exchange objects have changed dramatically from XFire. CXF’s Message and Exchange objects are devoid of all those helpful methods that were present in XFire but they make up for it by having get(Class) and get(String) methods which can be used to retrieve valuable information. It’s probably a good idea to look through Exchange.keySet() and Message.keySet() and see whats available to you in your interceptors. For example when a Fault occurs, the message.get(Exception.class) returns the exception that was thrown to cause the fault. Also note that the information present in these maps varies depending on what Phase you’re in.

Now to the WS-Security example. CXF just added support for configuring interceptors using annotations which means configuring WS-Security for our web services just got easier.

Here’s the service interface and implementation.

@WebService
public interface SportsService {
    public String getTeam();
        return "Arsenal";
    }
}

@WebService(
    serviceName="SportsService",
    endpointInterface="ca.utoronto.sis.cxfapp.SportsService")
@InInterceptors(interceptors={
        "com.arsenalist.cxfapp.WSSecurityInterceptor"
})
public class SportsServiceImpl implements SportsService {

    public String getTeam() {
        return "Arsenal";
    }
}

I’ve added a single in interceptor called WSSecurityInterceptor which is a class that we’ll write. In XFire we also needed a DomInHandler and a DomOutHandler for each service implementation, none of that is required here. WSSecurityInterceptor will just wrap the WSS4JInInterceptor class, the reason we can’t just specify WSS4JInInterceptor as an annotation is because we need to set custom properties on it such as using UsernameToken authentication.

The other thing WSSecurityInterceptor does is add a ValidateUserTokenInterceptor which is similar to ValidateUserTokenHandler in the XFire examples. Since WSS4J validates a UsernameToken only if it finds a security header we need to cover the case where no security header is specified. ValidateUserTokenInterceptor just makes sure the username, password, nonce and timestamp are specified before even considering it a valid request. Here’s the WSSecurityInterceptor and the PasswordHandler class:

public class WSSecurityInterceptor extends AbstractPhaseInterceptor {

    public WSSecurityInterceptor() {
        super(Phase.PRE_PROTOCOL);
    }
    public WSSecurityInterceptor(String s) {
        super(Phase.PRE_PROTOCOL);
    }

    public void handleMessage(SoapMessage message) throws Fault {

        Map props = new HashMap();
        props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
        props.put(WSHandlerConstants.PW_CALLBACK_REF, new PasswordHandler());

        WSS4JInInterceptor wss4jInHandler = new WSS4JInInterceptor(props);
        ValidateUserTokenInterceptor userTokenInterceptor = new ValidateUserTokenInterceptor(Phase.POST_PROTOCOL);

        message.getInterceptorChain().add(wss4jInHandler);
        message.getInterceptorChain().add(new SAAJInInterceptor());
        message.getInterceptorChain().add(userTokenInterceptor);
    }
}

public class PasswordHandler implements CallbackHandler {
    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {
        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
        if (pc.getIdentifer().equals("arsenal")) {
            pc.setPassword("gunners");
        }
    }
}

Note that the ValidateUserTokenInterceptor is invoked in a later phase than WSS4JInterceptor. Here’s the ValidateUsertokenInterceptor class:

public class ValidateUserTokenInterceptor extends AbstractPhaseInterceptor {

    public ValidateUserTokenInterceptor(String s) {
        super(s);
    }

    public void handleMessage(SoapMessage message) throws Fault {
        boolean userTokenValidated = false;
        Vector result = (Vector) message.getContextualProperty(WSHandlerConstants.RECV_RESULTS);
        for (int i = 0; i &lt; result.size(); i++) {
            WSHandlerResult res = (WSHandlerResult) result.get(i);
            for (int j = 0; j &lt; res.getResults().size(); j++) {
                   WSSecurityEngineResult secRes = (WSSecurityEngineResult) res.getResults().get(j);
                    WSUsernameTokenPrincipal principal = (WSUsernameTokenPrincipal) secRes
                            .getPrincipal();

                    if (!principal.isPasswordDigest() ||
                            principal.getNonce() == null ||
                            principal.getPassword() == null ||
                            principal.getCreatedTime() == null) {
                        throw new RuntimeException("Invalid Security Header");
                    } else {
                        userTokenValidated = true;
                    }
                }
            }
        }
        if (!userTokenValidated) {
            throw new RuntimeException("Security processing failed");
        }
    }
}

Now we have a service implementation annotated in a way where it is WS-Security enabled and is also registered as a web service. The final step remaining is to expose it as a consumable endpoint. That can be achieved by either of the following ways:

Using the fully qualified class name:

<jaxws:endpoint
   id="helloWorld"
   implementor="com.arsenalist.cfxapp.SportsServiceImpl"
   address="/SportsService" />

Or by referring to a Spring bean corresponding to the @WebService annotated class. This would be more prudent if you’re using Dependency Injection in your service implementations.

<bean id="sportsServiceImpl" class="com.arsenalist.cfxapp.SportsServiceImpl"/>

<jaxws:endpoint
   id="sportsService"
   implementor="#sportsServiceImpl"
   address="/SportsService" />

Finally you could also just use good ‘ol fashioned Spring beans. This comes in handy if you wan to specify a different binding like Aegis:

<bean id="aegisBean" class="org.apache.cxf.aegis.databinding.AegisDatabinding"/>
<bean class="org.apache.cxf.frontend.ServerFactoryBean" init-method="create">
	<property name="serviceBean" ref="registrationSoapService"/>
	<property name="address" value="/services/1_0_0/Registration"/>
	<property name="dataBinding" ref="aegisBean"/>
</bean>

The CXF documentation which shows how to configure the web.xml is pretty straightforward.

If you’re using Maven, the dependencies section of the pom.xml might look something like this. Remember that support for configuring interceptors via annotations was just added so you have to access the SNAPSHOT repositories instead of the main one.

<repositories>
    <repository>
        <id>apache-snapshots</id>
        <name>Apache SNAPSHOT Repository</name>
        <url>http://people.apache.org/repo/m2-snapshot-repository/</url>
        <snapshots>
        <enabled>true</enabled>
        </snapshots>
    </repository>
    <repository>
        <id>apache-incubating</id>
        <name>Apache Incubating Repository</name>
        <url>http://people.apache.org/repo/m2-incubating-repository/</url>
    </repository>
</repositories>
<dependencies>
    ...
    <!-- spring beans, core, context, web 2.0.6 -->
    ...
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http</artifactId>
        <version>2.1-incubator-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-core</artifactId>
        <version>2.1-incubator-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxws</artifactId>
        <version>2.1-incubator-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-ws-security</artifactId>
        <version>2.1-incubator-SNAPSHOT</version>
    </dependency>
    ...
<dependencies>

Thanks for reading.

Spring’s AOP support can’t be ignored

You see I’ve never actually written many (any?) AOP classes but there’s enough talk about it splashed all over the internet that even though it might be a worthless concept that you’ve never used or cared about, you’re bound to encounter it at some point. A fellow GO Train rider once told me it was the thing to know if you want to have a Java job in five years. That made me read the AspectJ in Action book which makes you feel guilty about not using AOP. I don’t talk to that guy anymore. Then there’s Adrian Colyer who will have you believe that AOP is the glue that ties every enterprise application together and without it you might be writing code that is hanging on by threads.

Now I realize for some of you this might bring flashbacks to 2004 but bear with me. A few days ago I had to catch an Exception in the DAO layer and translate it to something else, now normally this very simple problem is solved by 95% of the monkeys by using a try/catch on the Exception and throwing something more worthy of being bubbled up. But if the same DAO method is being executed in different places in your application you might have to do separate try/catch blocks for each, something which is totally acceptable, clear, concise and happening for ages. There’s nothing wrong with it.

But there is an AOP way of doing this outlined pretty clearly in the docs where you write a pointcut and provide advice on the execution of the event. No try/catch blocks, the client code is devoid of any knowledge about exceptions. Spring’s AOP support makes doing this the AOP way very easy, but is it overkill? I don’t know, I guess it depends on your style of development.

So to replace the generic try/catch mechanism with the AOP way, first declare a pointcut:

package com.arsenalist.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class SystemArchitecture {

    @Pointcut("execution(* com.arsenalist.dao.*.*(..))")
    public void daoOperation() {}
}

Once we’ve specified what methods to monitor using pointcuts, give advice on what should happen when the pointcut is executed.

package com.arsenalist.aop;

import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class DaoExceptionTranslator {

    @AfterThrowing(
      pointcut="com.arsenalist.aop.SystemArchitecture.daoOperation()",
      throwing="ex")
    public void translateException(Exception ex) {
        throw new RuntimeException("Generic message");
    }
}

With the above setup any method executed in the com.arsenalist.dao.*.* packages will be translated into a RuntimeException. I’m assuming that the interfaces reside in com.arsenalist.dao package and the implementations in a package underneath that. Here’s the Spring configuration needed:

<bean id="daoExceptionTranslator" class="com.arsenalist.aop.DaoExceptionTranslator"/>
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />

Most importanly the Maven POM should look something like this:

<dependency>
    <groupId>aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.5.3</version>
</dependency>
<dependency>
    <groupId>aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.5.3</version>
</dependency>
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib-nodep</artifactId>
    <version>2.1_3</version>
</dependency>
<dependency>
    <groupId>asm</groupId>
    <artifactId>asm-all</artifactId>
    <version>2.2</version>
</dependency>

Although there is a newer version of ASM available, it doesn’t seem to be compatible with Spring AOP.

There can be many arguments against this setup, the main one being that you’re unable to handle the same Exception differently depending on where it’s being called from. To do that you’d have to specify another pointcut and another advice on how to handle it. You also lose all call-context information because you’re assuming that everthing you need to handle the exception is in the Exception object.

But in the general sense it does seem to be an improved method of executing baseline operations when a particular event occurs. The docs get you thinking about other places where you can use AOP proxies instead of the “normal” way of doing things and it’s pretty easy to get sucked into “convert everything to AOP mode”.

If you’re afraid of proxies, this is not for you. Every call to the DAO layer happens via a proxy which is necessary to achieve the intended effect. I’m not sure what the performance penalites of using proxys on every single call to the DAO layer are but if you go this route, CGLIB proxies are apparently much faster than their JDK counterparts. Either way, if you haven’t tried out AOP but are sick of hearing the sound of it, give Spring AOP a shot. It’s probably worth it.

Unit Testing Struts 2 Actions wired with Spring using JUnit

Hopefully this entry serves as some search engine friendly documentation on how one might unit test Struts 2 actions configured using Spring, something I would think many, many people want to do. This used to be done using StrutsTestCase in the Struts 1.x days but Webwork/Struts provides enough flexibility in its architecture to accommodate unit testing fairly easily. I’m not going to go over how the Spring configuration is setup. I’m assuming you have a struts.xml file which has actions configured like this:

<struts>
 <package namespace="/site" extends="struts-default">
  <action name="deletePerson" class="personAction"
                  method="deletePerson">
   <result name="success">/WEB-INF/pages/person.jsp</result>
  </action>
 </package>
 ...
</struts>

You also might have an applicationContext.xml file where you might define your Spring beans like this.

<beans>
 <bean id="personAction"
  class="com.arsenalist.action.PersonAction"/>
 ...
</beans>

Then of course you also need to have an action which you want to test which might look something like:

public class PersonAction extend ActionSupport {

  private int id;

  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String deletePerson() {
    ....
    return SUCCESS;
  }
}

Remember than in Struts 2, an action is usually called before and after various other interceptors are invoked. Interceptor configuration is usually specified in the struts.xml file. At this point we need to cover three different methods of how you might want to call your actions.

  1. Specify request parameters which are translated and mapped to the actions domain objects (id in the PersonAction class) and then execute the action while also executing all configured interceptors.
  2. Instead of specifying request parameters, directly specify the values of the domain objects and then execute the action while also executing all configured interceptors.
  3. Finally, you just might want to execute the action and not worry about executing the interceptors. Here you’ll specify the values of the actions domain objects and then execute the action.

Depending on what you’re testing and what scenario you want to reproduce, you should pick the one that suits the case. There’s an example of all three cases below. The best way I find to test all your action classes is to have one base class which sets up the Struts 2 environment and then your action test classes can extend it. Here’s a class that could be used as one of those base classes.

See the comments for a little more detail about whats going on. One point to note is that the class being extended here is junit.framework.TestCase and not org.apache.struts2.StrutsTestCase as one might expect. The reason for this is that StrutsTestCase is not really a well written class and does not provide enough flexibility in how we want the very core Dispatcher object to be created. Also, the interceptor example shown in the Struts documentation does not compile as there seems to have been some sort of API change. It’s been fixed in this example.

import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.ActionProxyFactory;
import junit.framework.TestCase;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.Dispatcher;
import org.apache.struts2.views.JspSupportServlet;
import org.springframework.context.ApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.ContextLoader;

import java.util.HashMap;

/**
 * @author Zarar Siddiqi
 */
public abstract class BaseStrutsTestCase extends TestCase {
    private static final String CONFIG_LOCATIONS = "META-INF/applicationContext-app.xml," +
                "META-INF/applicationContext-security.xml";
    private static ApplicationContext applicationContext;
    private Dispatcher dispatcher;
    protected ActionProxy proxy;
    protected static MockServletContext servletContext;
    protected static MockServletConfig servletConfig;
    protected MockHttpServletRequest request;
    protected MockHttpServletResponse response;

    public BaseStrutsTestCase(String name) {
        super(name);
    }

    /**
     * Created action class based on namespace and name
     * @param clazz Class for which to create Action
     * @param namespace Namespace of action
     * @param name Action name
     * @return Action class
     * @throws Exception Catch-all exception
     */
    @SuppressWarnings("unchecked")
    protected <t> T createAction(Class<t> clazz, String namespace, String name)
            throws Exception {

        // create a proxy class which is just a wrapper around the action call.
        // The proxy is created by checking the namespace and name against the
        // struts.xml configuration
        proxy = dispatcher.getContainer().getInstance(ActionProxyFactory.class).
                createActionProxy(
                namespace, name, null, true, false);

        // by default, don't pass in any request parameters
        proxy.getInvocation().getInvocationContext().
                setParameters(new HashMap());

        // do not execute the result after executing the action
        proxy.setExecuteResult(true);

        // set the actions context to the one which the proxy is using
        ServletActionContext.setContext(
                proxy.getInvocation().getInvocationContext());
        request = new MockHttpServletRequest();
        response = new MockHttpServletResponse();
        ServletActionContext.setRequest(request);
        ServletActionContext.setResponse(response);
        ServletActionContext.setServletContext(servletContext);
        return (T) proxy.getAction();
    }

    protected void setUp() throws Exception {
        if( applicationContext == null ) {
            // this is the first time so initialize Spring context
            servletContext = new MockServletContext();
            servletContext.addInitParameter(ContextLoader.CONFIG_LOCATION_PARAM,
                    CONFIG_LOCATIONS);
            applicationContext = (new ContextLoader()).initWebApplicationContext(servletContext);

            // Struts JSP support servlet (for Freemarker)
            new JspSupportServlet().init(new MockServletConfig(servletContext));
        }
        // Dispatcher is the guy that actually handles all requests.  Pass in
        // an empty. Map as the parameters but if you want to change stuff like
        // what config files to read, you need to specify them here.  Here's how to
        // scan packages for actions (thanks to Hardy Ferentschik - Comment 66)
        // (see Dispatcher's source code)
        HashMap params = new HashMap();
        params.put("actionPackages", "com.arsenalist.action");
        dispatcher = new Dispatcher(servletContext, params);
        dispatcher.init();
        Dispatcher.setInstance(dispatcher);
    }
}

By extending the above class for our action test classes we can easily simulate any of the three scenarios listed above. I’ve added three methods to PersonActionTest which illustrate how to test the above three cases: testInterceptorsBySettingRequestParameters, testInterceptorsBySettingDomainObjects() and testActionAndSkipInterceptors(), respectively.

public class PersonActionTest extends BaseStrutsTestCase {

 /**
  * Invoke all interceptors and specify value of the action
  * class' domain objects directly.
  * @throws Exception Exception
  */
 public void testInterceptorsBySettingDomainObjects()
         throws Exception {
  PersonAction action = createAction(PersonAction.class,
                "/site", "deletePerson");
  action.setId(123);
  String result = proxy.execute();
  assertEquals(result, "success");
 }

 /**
  * Invoke all interceptors and specify value of action class'
  * domain objects through request parameters.
  * @throws Exception Exception
  */
 public void testInterceptorsBySettingRequestParameters()
                     throws Exception {
  createAction(PersonAction.class, "/site", "deletePerson");
  request.addParameter("id", "123");
  String result = proxy.execute();
  assertEquals(result, "success");
 }

 /**
  * Skip interceptors and specify value of action class'
  * domain objects by setting them directly.
  * @throws Exception Exception
  */
 public void testActionAndSkipInterceptors() throws Exception {
  PersonAction action = createAction(PersonAction.class,
                  "/site", "deletePerson");
  action.setId(123);
  String result = action.deletePerson();
  assertEquals(result, "success");
 }
}

The source code for Dispatcher is probably a good thing to look at if you want to configure your actions more specifically. There are options to specify zero-configuration, alternate XML files and others. Ideally the StrutsTestCaseHelper should be doing a lot more than what it does right now (creating a badly configured Dispatcher) and should allow creation of custom dispatchers and object factories. That’s the reason why I’m not using StrutsTestCase since all that does is make a couple calls using StrutsTestCaseHelper.

If you want to test your validation, its pretty easy. Here’s a snippet of code that might do that:

 public void testValidation() throws Exception {
  SomeAction action = createAction(SomeAction.class,
                  "/site", "someAction");
  // lets forget to set a required field: action.setId(123);
  String result = proxy.execute();
  assertEquals(result, "input");
  assertTrue("Must have one field error",
                  action.getFieldErrors().size() == 1);
 }
 

This example uses Struts 2.0.11 and Spring 2.0.6. That about sums things up.

Updated on November 4th, 2007 to make it a little simpler and compatible for newer versions of Struts and Spring. Thanks to Haroon Rafique.

Google Guice too self-righteous, stick with Spring

I like Guice, it’s a nice little tool that gets you all excited by doing Dependency Injection using annotations. That’s where it ends though, it really does. Once you’re past the high of using @Inject in a couple of your classes and on to doing something a little more complex, you realize that you’re a little stuck. And by stuck I don’t mean “totally f***ed” I just mean, you’re going to have to jump through some hoops to get it working, one of those hoops might even be refactoring for the sake of using Google Guice and throwing around annotations where you really don’t want annotations, like method parameters. The Guice guys will tell you your code probably sucked anyways and the refactoring is only helping your design – I wouldn’t buy it.

To me object lifecycle management is huge, you know, those methods for your classes which Spring so kindly allows using the InitalizingBean interface or init-method/destroy-method attributes, well that apparently is blasphemy to the Guice folk. Suffice to say they consider it bad practice and horrible design that one of your objects might need some initialization past the actual object creation. Some poor sap had a pretty damn good idea of having @Initialize type annotations for a method you might like to invoke after the object has been created, but he was quickly shot down by the Guice head-honcho who wasn’t convinced that there was a legitimate use-case for this. This effectively kills off anyone who might try to port their application over from Spring – their chief competitor. Instead of lifecycle methods, they want you to implement something called Provider interceptors, yeah, like that’s true DI!

The configuration is a mess, now whoever thinks they’d rather write Java code to configure their DI or IoC stuff instead of XML is beyond f***ed. That’s like saying why use Ant when you can just write one big Java class and do everything inside the main() method. I don’t care how hard they try to make Java code look like English, it still won’t cut it for me. If you prefer having classes in your application that have code like bind(Service.class). to(ServiceImpl.class). in(Scopes.SINGLETON) instead of an XML file, good for you, but I don’t see any benefit whatsoever in adopting this approach. I only see losses: the need for compilation, your configuration spread out in Java classes and difficulty in integrating your “Modules” with other tools.

Guice is also counting on you to create annotations of your own so that you can mark your own source code to help Guice figure out what it needs to do. Prime example is injecting constants, to inject a constant you would need to create a marker annotation, MyConstant and then do a bindConstant().annotatedWith(MyConstant.class).to(123456). Or you could use the @Named annotation which further clutters up your code base to the tune of introducing magic strings. I feel I have to do too much work to get Guice to behave the way I want it to behave, now I’m not lazy and am ready to put forth the effort but it shouldn’t come at the expense of writing custom Providers every time I need to play with a JAR’ed up class.

The good part about Guice is that you can use annotations for DI but the bad part is how messy the configuration classes can become, especially if you’re using third party JARs. The other thing that confuses me is that the Guice team seems to be very concerned about crossing some phantom preset boundaries that would make Guice do “too much” – the lifecycle methods are a prime example. If you’re seriously thinking about challenging Springb shouldn’t you provide a path for people who might actually test the migration? The best you can find is Eric Burke migrating a pea sized application over from Spring which doesn’t say much more than what the Guide says. I also lost faith in the Names class which I hoped would relieve some of the stress of wiring using Java but no such luck since Properties can’t resolve nested keys, but this class is a step in the right direction. They just need something like this, except something that can read in the interface to implementation mappings and other third party classes configuration.

I have a funny feeling that once Spring comes out with annotations for DI, the hype about Guice will die down significantly. Guice would be wise (I think) to actually have a bridge to allow for XML configuration as a supplement for wiring classes (I know it sounds crazy Bob). It would greatly eliminate the need to write Providers which I even feel yucky writing knowing that I’m actually writing code just for configuration sakes. Am I being weird in my thinking that we’re past the point of configuration in unadulterated Java code? I feel whatever is gained with annotations is immediately lost with the woeful configuration technique.