Archive | Spring

Grails vs Roo

Grails vs Roo

We’re great fans of Grails so we were very excited when we heard about Roo. Both frameworks promise rapid application development but Roo claims to have no runtime overhead. Can it live up to the hype?

Whilst Grails and Roo both aim to simplify the developer’s life they approach it in different ways. Grails is built on top of groovy and adds a lot of “magic” at runtime whereas Roo is essentially a code generation utility.

Performance

The benefit of compile time code generation is of course performance. A Roo powered application will almost always be faster than a Grails powered app but the performance “hit” associated with Grails is not as great as people sometimes think.

When we have run into performance problems in Grails the bottleneck in invariably a couple of methods or closures which perform computationally expensive calculations. Groovy implicitly uses BigIntegers for division which imposes a big performance hit. Extracting such calculations to static java methods which use floats often speeds up execution time by as much as 90%. Another area where Grails performance is lacking is the rendering engine behind the GSPs and specifically the way tag libraries are used. Switching to another rendering engine can significantly improve performance.

Both Roo and Grails can be tweaked to improve performance without making changes to the code base. Judicious use of caching and transaction management will give significant performance increases for both platforms. The use of transactions is especially significant for grails apps because by default grails will try to create a transaction for every request which is far from ideal.

So in summary out of the box grails is considerably slower than a Roo powered app but with a bit of tweaking we have found that grails apps can come very close to “traditional” java ones and certainly acceptable for all but the most demanding of applications.

Skills

To make the best use of Grails a developer must have a good grasp of Groovy whereas Roo is pure java so there is no need to learn another language. This shouldn’t be underestimated, I believe that any experienced Spring developer will have no trouble learning Groovy … the question is do you have the time to learn Groovy. Top developers are in high demand and getting time off to study something new is often easier said than done!

Grails and groovy is not hard but to become proficient you do need to spend a fair amount of time with real world examples. If you are a java developer and you have the chance to work on a grails project I would say jump at it … you’ll love it!

In contract a competent java developer can be up to speed and developing productive Roo apps in days. The code that is generated will look familiar and you’ll feel confident to experiment to get the best results. Roo is also ideally suited to more junior developers who may not be comfortable with some of the more “esoteric” features of groovy and grails but just want a framework that will save them a bit of time.

Availability of libraries/plugins

Roo is built on top of Maven so dependency management is a breeze and there is an extensive library of code available. In contrast grails relies on plugins which have a limited availablity. Grails can be used with Maven but it’s a painful experience and not something we would recommend. This is an area where Roo wins hands down. Ide support for grails projects is also lacking, even Spring own ide (STS) doesn’t have a specific groovy editor and debugging a grails application is not for the faint hearted. Grails generates a lot of code at runtime so the code you see in your debugger bears little relation to the code actually running. This can be a major headache but careful use of breakpoints and logging statements can ease the pain somewhat.

Maintenance

We’re not big fans of code generation tools, my own view is that if you find yourself writing or generating a lot of boilerplate code and config there is something wrong with the structure of your application. The core spring framework has been moving towards convention over configuration in recent releases, annotation driven controllers are the best example of this. Roo builds on this but it’s nowhere near Grails in terms of ease of maintenance. We are still amazed at just how little code we need to write to deliver a fully functional Grails powered app.

We have not yet developed and maintained any production grade Roo apps but my guess is that it could actually act as an impediment to the long term success of the project. I say this because I suspect developers who may be under pressure with tight deadlines will tend to rely on the code generation rather than thinking how they can structure the application to minimize code duplication.

Conclusion

Grails and Roo are both great frameworks. The framework you choose will depend on your need for performance vs maintainability but ultimately I think the big factor will the level of skills in your team. An advanced developer will be able to develop amazing Grails apps that are far more maintainable than those developed using Roo. Junior developers will be able to develop a basic grails app but the moment you hit performance or threading issues you’ll need to climb quite a high wall. Roo can be used by developers of all levels to boost their productivity.

Posted in Spring9 Comments

Custom spring authorization

Custom spring authorization

Spring security is immensely powerful and flexible but it can seem a bit daunting to those who are new to the framework. Version 2.0 simplified things greatly by introducing the security namespace and RoR style convention over configuration however there is a downside to this simplification … the framework creates and configures many beans behind the scenes and it’s not immediately obvious how to change the default behavior. In this short post I will explain how Spring’s authorization mechanism works behind the scenes.

The most basic spring security configuration looks something like this:

<http auto-config='true'>
  <intercept-url pattern="/**" access="ROLE_USER" />
</http>

This configuration tells spring to restrict access to the application to only those users who have the role of “ROLE_USER”. Behind the scenes spring creates and wires up several beans that all play a role in the authorization process. I’m going to assume that we are protecting web urls (known as FilterInvocation’s in Spring) but I’ll cover method level security in a later post

Before we start let’s have a look at the key collaborators involved in spring authorization:

DelegatingFilterProxy

You will most likely have defined and mapped an instance of the DelegatingFilterProxy in your web.xml. This proxy allows Spring to create a number of filters needed for authentication and authorization. One such filter which is relevant to url authorization is the FilterSecurityInterceptor

FilterSecurityInterceptor

This is the primary entry point for url authorization, it intercepts requests and passes control to the AccessDecisionManager

AccessDecisionManager (Interface)

This is the primary interface responsible for Authorization. As the name implies Implementors are responsible for deciding whether to grant or deny access to a particular resource (known as a secure object in Spring). In the context of web based url security the secure object will be an instance of the FilterInvocation class. AccessDecisionManager’s key method is

void decide(Authentication authentication, Object secureObject,
 ConfigAttributeDefinition config)
 throws AccessDeniedException, InsufficientAuthenticationException

The authentication represents the principle (or “user”) accessing the system, the secureObject will be an instance of FilterInvocation. The config is basically a collection of name/value pairs that are passed to the class if they are needed.

Out of the box spring will create an instance of the AccessDecisionManager which supports role based authorization. We can write our own implementation if we need some custom behavior. Lets say we want to restrict access to admin user’s with particular IP addresses:

package com.test.security;

import java.util.Collection;

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.FilterInvocation;

public class NaiveAccessDecisionManager implements AccessDecisionManager {

 public void decide(Authentication authentication, Object secureObject,
     Collection attributes) throws AccessDeniedException,
     InsufficientAuthenticationException {

   // The supports method ensures we are dealing with FilterInvocations
   //  so we can safely cast the secure object
   FilterInvocation invocation = (FilterInvocation) secureObject;
   WebAuthenticationDetails requestDetails = (WebAuthenticationDetails) authentication.getDetails();

   if ("/secret.do".equals(invocation.getRequestUrl())) {
     boolean authorized = false;

     // only allow access if the user has the admin role a
     // and is within the correct IP range
     for (GrantedAuthority authority : authentication.getAuthorities()) {
       if ("ROLE_ADMIN".equals(authority.getAuthority()) && requestDetails.getRemoteAddress().startsWith("192.168.0")) {
         authorized = true;
       }
     }

     if (!authorized) {
       throw new AccessDeniedException("go away");
     }
   }
 }

 public boolean supports(Class clazz) {
   // This manager should be used for FilterInvocations (authorizing web
   // requests)
   return FilterInvocation.class.isAssignableFrom(clazz);
 }

 public boolean supports(ConfigAttribute config) {
   return true;
 }

}

We now need to tell spring to use our manager:

<bean:bean id="naiveAccessDecisionManager" class="com.test.security.NaiveAccessDecisionManager" />
<pre><pre>
<http auto-config="true" access-decision-manager-ref="naiveAccessDecisionManager">
 <!-- no need for interceptor element here because our accessDecisionManager has this hard coded -->
</http>

That would work but it’s not very nice.  For one thing we’re reimplementing spring’s role based access control which doesn’t make sense. It can also become messy if we have conditional logic

To simplify things Spring offers us the concept of “voters” which are polled by an AccessDecisionManager.

AccessDecisionVoter (interface)

Let’s have a quick look at the key method in the AccessDecisionVoter interface:

int vote(Authentication authentication, Object secureObject, ConfigAttributeDefinition config);

Voter’s can be chained together by an AccessDecisionManager to build complex authorization strategies. The way an AccessDecisionManager handles “votes” depends on it’s type; the Unanimous AccessDecisionManager requires all voters to say yes before allowing access. In contrast the Affirmative AccessDecisionManager just needs any one of the voters to say yes. Spring offers several concrete implementations of the AccessDecisionVoter, the most common of which is the RoleVoter.

A real world example

We recently did some work for a media company whose licensing and rights policy meant that they could only display content to users in the UK. We chose to implement a custom voter which would try to geolocate the visitors IP address and allow access if it was reported as being UK based:

package com.x;

public class IPVoter implements AccessDecisionVoter {

  public int vote(Authentication authentication, Object secureObject, Collection<ConfigAttribute> attributes) {

    if (authentication.getDetails() == null) {
      return AccessDecisionVoter.ACCESS_DENIED;
    }

    WebAuthenticationDetails details = (WebAuthenticationDetails) authentication.getDetails();
    String remoteIPAddress = details.getRemoteAddress();
    if (StringUtils.isBlank(remoteIPAddress)) {
      return AccessDecisionVoter.ACCESS_DENIED;
    }

    // checks the IP address using Quova
    return validateIPAddress(remoteIPAddress);
  }

  public boolean supports(ConfigAttribute att) {
    return true;
  }

  public boolean supports(Class clazz) {
    return FilterInvocation.class.isAssignableFrom(clazz);
  }
}

We then needed to wire up our new voter along with Spring’s RoleVoter:

<bean id="accessDecisionManager" class="org.springframework.security.vote.UnanimousBased">
  <property name="decisionVoters">
    <list>
      <bean class="org.springframework.security.vote.RoleVoter" />
      <bean class="com.x.ipVoter">
        <property name="quova" ref="quova" />
      </bean>
    </list>
</bean>

<security:http access-decision-manager-ref="accessDecisionManager">
...
</security>

Posted in Spring1 Comment