Basically I have one Controller that is permitted for regular user and I want to have the same controller to be accessible by admin in a different path. So I thought this would work:
@RestController
@PreAuthorize("hasRole('USER')")
@RequestMapping(value = "/user")
public class UserController {
@RequestMapping(value = "/name", method = RequestMethod.GET)
public String getName() {
return service.getCurrentUserName();
}
}
@RestController
@PreAuthorize("hasRole('ADMIN')")
@RequestMapping(value = "/admin")
public class UserController extends UserController{
}
But I can call both /user/name and /admin/name with the USER role. So it kind of ignores the PreAuthorize annotation on the subclass.
Is there any way to re-use the UserController methods and just add a different security PreAuthorize to them without rewriting them for Admin?
The controller methods are registered in superclass, so the superclass annotation applies.
The only way I know to have a kind of dynamic annotation, is to use a #root inside the @PreAuthorize. You could modify the parent class that way :
@RestController
@PreAuthorize("hasRole(#root.this.requiredRole)")
@RequestMapping(value = "/user")
public class UserController {
protected String getRequiredRole() {
return "USER";
}
...
}
And for the child class :
@RestController
@RequestMapping(value = "/admin")
public class AdminController extends UserController {
protected String getRequiredRole() {
return "ADMIN";
}
...
}
That way, the methods of the parent class will correctly require ADMIN role when called for a AdminController object, since the string value of @PreAuthorize will be preprocessed by SpEL, while still requiring USER role for a true UserController.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With