Monday, August 13, 2012

Writing your spring security expression language annotation - PART 2

We are now going into the second part of the tutorial. In this post, it will show you how to add a new custom expression for @PreAuthorize annotation. For example, I will show how to add a adminOnly() expression language to the security expression root.


Step 1: Define your custom security expression root class
You have to first create a new security expression root class. This class should be extended from the abstract class org.springframework.security.access.expression.SecurityExpressionRoot. You can add your custom

This class is similar to org.springframework.security.access.expression.method.MethodSecurityExpressionRoot but with your new custom method added. As an example, I just add a very simple mehod adminOnly() which check if the user has admin role.


public class MyMethodSecurityExpressionRoot extends SecurityExpressionRoot {
 
    private static  Logger logger = LoggerFactory.getLogger(MyMethodSecurityExpressionRoot.class);
 
    private Object filterObject;
    private Object returnObject;
    private Object target;
    
     
    public  boolean adminOnly() {
     logger.debug("haha -- check if this function is used by admin role only");
     return  this.hasAuthority("ADMIN");
    }
    
    public MyMethodSecurityExpressionRoot(Authentication a) {
  super(a);
    }

    public void setFilterObject(Object filterObject) {
        this.filterObject = filterObject;
    }

    public Object getFilterObject() {
        return filterObject;
    }

    public void setReturnObject(Object returnObject) {
        this.returnObject = returnObject;
    }

    public Object getReturnObject() {
        return returnObject;
    }

    void setThis(Object target) {
        this.target = target;
    }

    public Object getThis() {
        return target;
    }

}


Step 2: Define your custom expression handler class
To add custom security expression method, you cannot use the DefaultMethodSecurityExpressionHandler. You need to define a new expression handler class by extends the DefaultMethodSecurityExpressionHandler.

You have to override the createSecurityExpressionRoot() method to create your custom security expression root class.


public class MyMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler implements MethodSecurityExpressionHandler  {

   @Override
   protected SecurityExpressionRoot createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
  MyMethodSecurityExpressionRoot root = new MyMethodSecurityExpressionRoot(authentication);
         root.setThis(invocation.getThis());
         root.setPermissionEvaluator(getPermissionEvaluator());
         return root;
   }
}


Step 3: Register the custom expression handler in XML


<sec:global-method-security pre-post-annotations="enabled">
  <sec:expression-handler ref="expressionHandler"/>
</sec:global-method-security>

<bean id="expressionHandler" class="org.borislam.security.ExtendedMethodSecurityExpressionHandler">
  <property name="permissionEvaluator" ref="permissionEvaluator"/>
</bean>  

<bean id="permissionEvaluator" class="org.borislam.security.BasePermissionEvaluator"/>





Example usage:

@PreAuthorize("adminOnly()")
 public void doSomething() {
  System.out.println("doSomething!!!"); 
 }

No comments: