Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Writing Your Spring Security Expression Language Annotation

DZone's Guide to

Writing Your Spring Security Expression Language Annotation

Spring security expression language is very useful. It helps secure your service/web methods with one line of code.

· Java Zone
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

Spring security expression language is very useful. It helps secure your service/web methods with one line of code. It supports @PreAuthorize and @Secured. In the next three posts, I will talk about how to add custom behaviour to the @PreAuthorize annotation. 

Part 1 - Customize "hasPermission()" expression 
Part 2 - Add new customize method security expression 
Part 3 - Override default behaviour of spring security expression (e.g. hasRole() , permitAll() ...)

In this post, I will discuss how to add custom rules for permission-checking in your application. This is somewhat similar to what is described in Sold Craft's post. You can reference it for more details.

Step 1: Add configuration in your spring security xml file.

You should first add the DefaultMethodSecurityExpressionHandler. It will instantiate a default MethodSecurityExpressionRoot which provides you all the default security expression (e.g. isAuthenticated(), isAnonymous(),etc.). 

Besides, you have to add a permissionEvaluator for that ExpressionHandler. If you are using spring security ACL, you could use AclPermissionEvaluator. In our case, we would create a BasePermissionEvaluator as our permission evaluator. You will see in step 2 that we would define custom rules in this permission evaluator.

<sec:global-method-security pre-post-annotations="enabled">

  <sec:expression-handler ref="expressionHandler"/>
</sec:global-method-security>

<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandlerr">
    <property name="permissionEvaluator" ref="permissionEvaluator"/>
</bean>  

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

Step 2: Create your PermissionEvaluator class

You must define a class that implements the org.springframework.security.access.PermissionEvaluator. You have to override the hasPermission() method and define custom rules in this class.

In my example, the user object contains a HashMap which stores the permissions of the user. I will check the permission String against this Hashmap. This HashMap is populated during login by a filter. This part will not be skipped in this example. 

For simplicity I just ignore the targetDomainObject parameter in my example. By using the targetDomainObject, you can further define security rules on certain domain objects in your application.

public class BasePermissionEvaluator implements PermissionEvaluator{

 @Override
 public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
  boolean hasPermission = false;
  if ( authentication != null &&  permission instanceof String){

   //implement the permission checking of your application here   
   //you can just check if the input permission is within your permission list

   //In my example, the user object contains a HashMap which stored the permission of the user.
   //The HashMap<String, PrivilegeResult> is populated during using login by filter. This will not be shown in this example 

   User user = SecurityUtil.getUserCredential();
   HashMap<String, PrivilegeResult> pMap =user.getPrivilegeMap();
   PrivilegeResult privResult = pMap.get(permission); 
   hasPermission =  privResult.isAllowAccess();

  } else {
   hasPermission =false; 
  }
  return hasPermission;
 }

 @Override
 public boolean hasPermission(Authentication authentication,
   Serializable targetId, String targetType, Object permission) {
    throw new RimtimeException("Id and Class permissions are not supperted by this application");
 }
}

Step 3: Example usage

You could simply add your @PreAuthorize("hasPermission()") to secure your method.

@PreAuthorize("hasPermission(#user, 'allowDoSomething')")
 public String doSomething()
 {
  //do something
  System.out.println("Do something");
 } 

Original Post

 

Download Modern Java EE Design Patterns: Building Scalable Architecture for Sustainable Enterprise Development.  Brought to you in partnership with Red Hat

Topics:
java ,spring ,tips and tricks ,server-side ,spring security

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}