5

I am implementing an application which has some methods to which's access will be fully based on permissions. The permissions are implemented using Spring. The permissions are added using @PreAuthorize annotation on top of the methods. The problem is that I would like to have fully custom methods (EL) within the annotations. So what I would like to achieve is for instance:

@PreAuthorize("customAllowThis()")
public void foo() { }

I think there are two approaches:

Approach 1: Try to override SecurityExpressionRoot and add my custom methods there. I will use multiple authorisation services on different methods, so putting all specific methods to SecurityExpressionRoot would be a big chaos.

Approach 2: Create service and place the method there:

@Component
public class AuthorisationService {
    public boolean allowThis() {
         return true;
    }
}

and do something like:

@PreAuthorize("@authorisationService.customAllowThis()")
public void foo() { }

I much more prefer Approach 2 although it looks for me like it would bypass the "natural order" of Spring. Are there any good/best practices in terms of how to handle such situation? The point is that I wouldn't like to stick all specific methods into one class but from the other hand I wouldn't like to do something "dirty".

Taks
  • 2,033
  • 4
  • 18
  • 23
  • check this http://stackoverflow.com/questions/6632982/how-to-create-custom-methods-for-use-in-spring-security-expression-language-anno?rq=1 – Arturo Volpe Jul 22 '14 at 20:26
  • Hey I have seen this, but one person says its not possible in Spring 3.x and there is another comment where guy just does that.. I am a bit confused.! – Taks Jul 22 '14 at 20:30
  • You try something? or you are asking only for best practiques? – Arturo Volpe Jul 22 '14 at 22:22
  • 1
    Just asking for best practices.. – Taks Jul 23 '14 at 06:56
  • 1
    Also see this: https://stackoverflow.com/questions/17803406/best-way-to-create-custom-method-security-expression – Paul Nov 23 '18 at 20:57

1 Answers1

2

To achieve this, you can do the following :

  1. Create a custom annotation that accepts an array of allowed roles, something like this :

    @Allows({RoleEnum.ROLE1, RoleEnum.ROLE2 })

  2. using SPeL, we can invoke a custom method that will check if the user has these Roles, something like this :

    @PreAuthorize("myServiceClass.hasRoles(#roles)")

  3. in the service class, you can just validate the user roles against the roles from OAuth database, and perform any business logic in the service.

Manik Jain
  • 86
  • 4
  • Can you show some more code? How does the `@PreAuthorize` access the roles in the other annotation? I've been trying to figure out how to do that. – Kevin May 17 '23 at 16:40