Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call a private method in Spring @PreAuthorize

I am using Spring Security for permission checking on methods. I would like to call a private method to collect some data to send to hasPermission() method. Following is something I am trying to execute and I get SpelEvaluationException because Spring is looking for the localPrivateMethod in MethodSecurityExpressionRoot. Is there a way to achieve this? Thanks.

@PreAuthorize("hasPermission(new Object[]{#arg3, #localPrivateMethod(#arg1,#arg2)}, 'canDoThis')")  
public long publicMethod1(long arg1, long arg2, long arg3) {}

private String localPrivateMethod(long a1, long a2) {}
like image 660
M99 Avatar asked Aug 27 '13 16:08

M99


People also ask

What is @PreAuthorize annotation in spring boot?

Method-level security is implemented by placing the @PreAuthorize annotation on controller methods (actually one of a set of annotations available, but the most commonly used). This annotation contains a Spring Expression Language (SpEL) snippet that is assessed to determine if the request should be authenticated.

What is the use of @PreAuthorize annotation?

The @PreAuthorize annotation checks the given expression before entering the method, whereas the @PostAuthorize annotation verifies it after the execution of the method and could alter the result.

How does @PreAuthorize work in spring boot?

Spring Security provides method level security using @PreAuthorize and @PostAuthorize annotations. This is expression-based access control. The @PreAuthorize can check for authorization before entering into method. The @PreAuthorize authorizes on the basis of role or the argument which is passed to the method.

What's the difference between @secured and @PreAuthorize in Spring Security?

The difference between @Secured and @PreAuthorize are as follows : The main difference between @Secured and @PreAuthorize is that @PreAuthorize can work with Spring EL. We can access methods and properties of SecurityExpressionRoot while using @PreAuthorize but not with @Secured.


2 Answers

You will not be able to call a private method, but you will be able to call a method in another spring bean. In my app I have an @Component named permissionEvaluator. I then reference it in a @PreAuthorize like so:

@PreAuthorize("@permissionEvaluator.canViewImageSet( #imageSet, principal )")
@RequestMapping(value="/image", method=RequestMethod.GET )
public String getImage(
        @RequestParam(value="imageSet", required=false) ImageSet imageSet ) {
    // method body
}

PermissionEvaluatorImpl looks like this:

@Component(value="permissionEvaluator")
public class PermissionEvaluatorImpl implements PermissionEvaluator
{
    public PermissionEvaluatorImpl() {}

    /**
     * Determine if a user can view a given image.
     */
    public boolean canViewImageSet( ImageSet imageSet, UserDetailsAdapter user )
    {
        // code to see if they should view this image
    }
}

and PermissionEvaluator is my own interface with nothing special, just whatever methods I need to evaluate.

like image 117
digitaljoel Avatar answered Oct 06 '22 18:10

digitaljoel


Private methods cannot be called, but you can refer to "this component" through this.:

@PreAuthorize("hasPermission(new Object[]{#arg3, /* HERE: */ this.localPublicMethod(#arg1,#arg2)}, 'canDoThis')")   
public long publicMethod1(long arg1, long arg2, long arg3)
{
}

public String localPublicMethod(long a1, long a2)
{
}
like image 30
Mateusz Stefek Avatar answered Oct 06 '22 16:10

Mateusz Stefek