Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@PreAuthorize doesn't work with function which is called from another function

I am trying to understand spring security. I am using java-config instead of xml. I tried creating a controller and then tested @PreAuthorize notation. But in my given code this @PreAuthorize only works if I use it with the getActiveSessions function but it has no effect when I use it with getName function. So this code works as expected

public class DemoSessionController extends SessionController{

        @RequestMapping("/welcome/{a}")
        @PreAuthorize("hasRole('ROLE_ADMIN')")
        public String getActiveSessions(@PathVariable String a) {
            // TODO Auto-generated method stub
            String str = getName(a);
            return str;
        }

        public String getName(String name) {
            // TODO Auto-generated method stub
            return "This is "+name+"";
        }
    }

But this doesn't

public class DemoSessionController extends SessionController{

    @RequestMapping("/welcome/{a}")
    public String getActiveSessions(@PathVariable String a) {
        // TODO Auto-generated method stub
        String str = getName(a);
        return str;
    }

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    public String getName(String name) {
        // TODO Auto-generated method stub
        return "This is "+name+"";
    }
}

Can someone explain why the second case doesn't work and how can I make it work? Thanks !!

like image 234
varunkr Avatar asked Sep 11 '25 04:09

varunkr


1 Answers

As mentioned in the comments, annotations are only processed when the object is called from outside. There are a couple of solutions.

You could split the methods that need annotations to be processed in a separate object, e.g. an AdminObject which is annotated with

@PreAuthorize("hasRole('ROLE_ADMIN')")

on the class level. That way you don't need to annotate each method. You should mark internal methods in the class private to prevent them being used from outside. This requires to reorder the application logic, but it might helpful to have all the admin tasks in one object.

Another solution is obviously to add the required annotations for all tasks the a method does, including the ones executed by methods used by the public methods.

EDIT 1:

Added sample classes to make the proposed solution clearer

public class UserSessionController extends SessionController{
@Inject
private AdminFacade adminFacade;

@RequestMapping("/welcome/{a}")
public String getActiveSessions(@PathVariable String a) {
    return adminFacade.getName(a);
}
}

@PreAuthorize("hasRole('ROLE_ADMIN')")
public class AdminFacade {

public String getName(String name) {
    return "This is "+name;
}
public String getDetailsForAdmin(String param) {
    return "admin details";
}
}
like image 142
Guenther Avatar answered Sep 13 '25 18:09

Guenther