Karim Tawfik
Karim Tawfik

Reputation: 1506

How spring handle calling the customed method passed in the @PreAuthorize annotation

I am new to spring security, and recently worked on a project that require to do method level security.

I managed to handle it like below:

 @Repository
public class EmployeeDaoImpl{
    @PreAuthorize("@mySecurityService.canAdd('ROLE_ADMIN') ")
    public void addEmployee(EmployeeEntity employee) {
        try{
            this.sessionFactory.getCurrentSession().save(employee);         
        }catch(AccessDeniedException e){

        }
    }
}

    @Component
public class MySecurityService {

    public boolean canAdd(String user) {
        System.out.println("Entered has permission..........");
        if(user.equals("ROLE_ADMIN")){
            return false;
        }
        return false;
    }
}

so far so good, everthing is working fine and smoothly.

My question here is about performance, how spring behind the scenes handle calling the method in the @PreAuthorize(), do spring do any kind of object/method caching or proxy-ing, or every time call the method by reflection, and how this will affect the performance?

I've did a lot of search and only found this link, it helped me, but do you have any further explaination specific to @PreAuthorize case.

http://spring.io/blog/2007/07/19/debunking-myths-proxies-impact-performance/

Hope my question is clear, Thanks.

Upvotes: 1

Views: 453

Answers (1)

Mateusz Stefek
Mateusz Stefek

Reputation: 3856

First, the expression needs to be parsed, and only then it can be evaluated.

As a result of parsing, the expression is converted into a tree of SpelNodes. In particular, MethodReference is a SpelNode responsible for method calling.

The parsing part is cached well in PreInvocationAuthorizationAdvice.

The details of the implementation of MethodReferencecan be found here: org.springframework.expression.spel.ast.MethodReference org.springframework.expression.spel.ast.MethodReference#getValueInternal(...) org.springframework.expression.spel.support.ReflectiveMethodExecutor

There is caching and the java.lang.reflect.Method reference is evaluated only once (if the target object remains the same type).

So this is pretty the most that could have been done by Spring. Further improvements require byte code generation, which would be an overkill in my opinion.

Upvotes: 2

Related Questions