2014
07
August

Spring @PreAuthorize SpEL examples

If you’ve been using Spring Security at all, then you’re probably familiar with the PreAuthorize annotation, typically used in the following manner:

@PreAuthorize(value="hasRole('ROLE_SomeKindOfGrantedRole')")

But what makes @PreAuthorize even more useful is its support for Spring Expression Language (SpEL) to go beyond simple role checks. The following are a few examples of SpEL expressions that can harness other service classes/methods for validation.

Multiple possible roles invocation is a given, but it sets things up nicely as a basic example for multiple/nested conditionals. In this instance, the caller must have the AwesomeRole, and either of ReallyGoodBossRole or TotallyNiceGuyRole:

@PreAuthorize(value="hasRole('ROLE_AwesomeRole') and (hasRole('ROLE_ReallyGoodBossRole') or hasRole('ROLE_TotallyNiceGuyRole'))")

It’s also possible to invoke a Spring wired service within the SpEL. It’s not necessary to reference the service in any way with the class that the @PreAuthorize is defined within (you don’t need to @Autowire the service into the containing class). Spring will properly allocate the correct service class/method based on the unique name.

For example, if you wanted to locate a specific Domain object based on a passed ID, you could use something similar to the following. This checks that the user has the specified role, or makes sure the user is contained within the list of owners specified upon the domain object with the passed id:


@RequestMapping(value="/id/{domainObjectId}/dostuff", method=RequestMethod.POST, produces="application/json")
@PreAuthorize(value="hasRole('ROLE_DomainObjectAdmin') or @domainObjectServiceImpl.findDomainObject(#domainObjectId).getOwners().contains(#userAccount.getEmployee())")
public String setObjectiveComplete(@PathVariable String domainObjectId, UserAccount userAccount) {
// Do stuff
}

There are a lot of things going on here, but I’ll try to break it down into a few specific points:

The domainObjectId is passed as a path variable itself. Any variable the method accepts, whether @PathVariable or @RequestParam, may be referenced within the SpEL expression as long as it is preceeded with a hash (#). The key thing to remember here is to use the name of the variable in the method, not the name of the parameter passed in (if you map the parameter “thisEmployeeId” to the String employeeId, in the SpEL you would reference it by using #employeeId).

You can also see that the domainObjectServiceImpl is being invoked to look up the object based on the passed id.  The domainObjectServiceImpl is not referenced in any way in the containing class. Spring is able to find the proper class/method automagically.

These are some pretty basic examples of the usefulness of @PreAuthorize combined with SpEL.  Hopefully the examples can help you iron out your own implementations.  If you have any questions or suggestions feel free to comment and I’d be happy to help out.

Tagged with: , , — Posted in Software Development