Search code examples
javaspringspring-securityinterceptor

Is it possible to prefetch database object from auth/custom annotation in Spring boot


I have the following endpoint in my Spring MVC controller:

@RestController
public class ToolsController {

    @GetMapping("/v1/auth-check/....id....")
    @RolesAllowed(...)
    @MyCustomPermissions(...)
    public MyResult checkAuth(...., int databaseId, ....) {

Here roles allowed is a standard annotation, which checks with user data and prevent method from being called without permissions.

Now I want additionally to check permissions with the help of a data, which is contained in a database object, identified by parameter databaseId. Can I read this object from somewhere so that my annotation also prevent method from being called?

I can parse request separately in HandlerInterceptorAdapter#preHandle

This is bad because I will duplicate Spring's work. Are there any other mechanisms?


Solution

  • If the object you're referring to as "database object" is the result returned by checkAuth() then sure you can examine its contents @PostAuthorize. If a SpEl expression provided as an argument would not match, then request processing would fail with an exception.

    It would look like this:

    @PostAuthorize("returnObject.databaseId ... <- your-conditional-logic-here")
    

    Reminder: to make this annotation enabled, prePostEnabled attribute of the @EnableGlobalMethodSecurity (which annotates configuration class) needs to be set to true (I guess you're aware of this, but a random reader might be not):

    @EnableGlobalMethodSecurity(prePostEnabled=true)
    

    In case if you didn't refer to the resulting object, then you can retrieve this "database object" right inside the SpEl-expression because we're free to use any Beans and invoke their methods. So it still can be using @PostAuthorize.

    Also, it's worth noticing:

    • That it's better keep SpEl-expression as simple as possible, since its hard to test.
    • HandlerInterceptorAdapter is deprecated since release version 5.3, so it's not a great alternative.