How to secure your domain objects using Spring Security

Sitewide-10usd300x250 We often need to restrict access to our domain objects based on who has logged in. Take this business rule for example – “an employee record could be edited only by her department head.”

Spring Security does support ACL to handle this kind of domain object security requirments, but that often seems too heavy weight. In this post, let’s instead discuss a light-weight pattern for this. If you have gone through Module III of our Spring course, you’ll find it quite familiar. So, below are the steps.

1) Configure method-level authorization

You may be knowing that we can restrict access to our service methods using pre/post annotations. To configure it, just annotate one of your configuration classes with @EnableGlobalMethodSecurity(prePostEnabled = true). E.g.

@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class FooApplication {

	public static void main(String[] args) {
		SpringApplication.run(FooApplication.class, args);
	}
}

Now, to restrict access to a method, we can annotate it with with pre/post annotations like @PreAuthorize. Here is an example:

@PreAuthorize("isAuthenticated()")
public void editEmployee(Employee employee) {
   ...
}

@PreAuthotize takes a Spring EL expression, which is isAuthenticated() in the above case.

Here is a list of methods that can be used in the expression. Of those, hasPermission(Object target, Object permission) ‘ll be of our interest here.

2) Use hasPermission

hasPermission decides whether the currently logged-in user should be allowed a particular operation on a particular object. It can be used as below:

@PreAuthorize("hasPermission(#employee, 'edit')")
public void editEmployee(Employee employee) {
   ...
}

The above method will be executed only if the current-user has edit permission to the employee parameter. Otherwise, an AccessDeniedException will be thrown.

For this to work, we need to supply a PermissionEvaluator.

3) Code a PermissionEvaluator

A PermissionEvaluator implementation would look like this:

@Component
public class PermissionEvaluatorImpl implements PermissionEvaluator {

	@Override
	public boolean hasPermission(Authentication auth,
			Object targetDomainObject, Object permission) {

		// return true if "auth" has "permission" permission for the user.
		// Current-user can be obtained from auth.
	}

	...
}

As you see above, the PermissionEvaluatorImpl has a hasPermission method, which receives three parameters:

  1. The Spring Security authentication object, from which we can get the currently logged in user
  2. The object for which the permission has to be checked
  3. The permission

Leave a Reply

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