Implementing custom authorization function for Spring’s @Pre and @Post annotations

Implementing custom authorization function for Spring’s @Pre and @Post annotations

The @Pre and @Post annotations provide mechanism to enforce access control by using Spring EL expressions. EL expressions have the ability to invoke methods. Spring provides some default methods that can be used to implement authorization. One such method is hasRole(). We can use it in a @Pre and @Post annotation to ensure that the user executing the code has specific role. Let me give you a short example:

This code snippet demonstrates that the method someAction() is secured and only users with the role “USER” can execute it. There are several more build-in methods that are described in Expression-Based Access Control section of the Spring Security Reference. However sometimes the build-in functionality is not enough to address all  of the system’s needs but luckily it is quite easy to implement our custom authorization method.

Spring allows us to reference components in the @Pre and @Post annotations. We can create a service and call its methods in the @PreAuthorize annotation. The requirement is the methods to return true or false. If a method returns false, spring throws AccessDeniedException. In a recent project we created a class called SecurityService where we put all methods that we used in the authorization. Let me show you an example:

As you can see, we have one method that returns true if called with parameter = 1 and false otherwise. Now this method doesn’t provide some authorization logic, but it will serve as good example of how we can call methods with parameters in the @Pre and @Post annotations. Let’s say that we have some method that we want to secure. We can call our hasAccess method like this:

Notice how we reference our SecurityService with the symbol ‘@’ and the name starting with a lower case. Then we can call the public methods of our service. We called the method hasAccess with parameter 2. This will always return false and spring will always throw AccessDeniedException before the execution of the method. This is not very useful, however we can implement other logic that takes in account some user attributes and so on. If we wanted to implement the method hasRole() ourselves we would have a method in our SecurityService that takes a String parameter and checks if the user has a role that equals the passed parameter.

Let me show you another very useful thing that we can do in the @Pre and @Post annotations. I will start with the code and explain afterwards:

Here I modified the method printStuff from before, to include a parameter called number. Spring allows us to pass the value to our hasAccess() method, by referencing the number parameter with # symbol. So for example if I call the method printStuff with value 1, spring will allow me to execute the method and it will print “Printing … 1”. If I call the method printStuff with anything else, I won’t be able to execute the method. This is very useful, because we can implement logic which allows execution of a method based on the passed parameters.

I hope you find this article useful. Do you know a better way to add a custom logic in the @Pre and @Post annotations?

Veselin Pavlov

Dev Manager and Partner at Dreamix

More Posts - Website

Follow Me:

Do you want more great blogs like this?

Subscribe for Dreamix Blog now!