To trigger PermissionEvaluator , you have to use hasPermission() in @PreAuthorize.
There are 2 versions of hasPermission() which are :
(1) @PreAuthorize("hasPermission('foo' ,'bar')") which will call
boolean hasPermission(Authentication authentication, Object targetDomainObject,Object permission);
/** targetDomainObject = 'foo', permission = 'bar' **/
(2) @PreAuthorize("hasPermission('foo' ,'bar','baz')") which will call
boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission);
/** targetId = 'foo' , targetType = 'bar' , permission = 'baz' **/
In both cases , the Authentication parameter is the Authentication token get from the SecurityContext.
One thing to note is that when configuring @PreAuthorize("hasPermission()"), you can use #foo , @P or @Param from spring data to specify which argument in the protected method will be used to invoke the PermissionEvaluator . See this for more details.
In your case , you could do something like:
@PreAuthorize("hasPermission('#id', 'getOrder')")
public EntityModel<Order> getOrders(@PathVariable Long id) {
}
and the PermissionEvaluator looks like :
public class MyPermissionEvaluator implements PermissionEvaluator {
@Override
public boolean hasPermission(Authentication auth, Object targetDomainObject, Object permission) {
MyAuthentication myAuth = (MyAuthentication) auth;
Long targetId = (Long) id;
String permssionStr = (String) permission;
if(permssionStr.equals("getOrder")){
return myAuth.getUserId().equals(targetId);
}else if(permssionStr.equals("xxxx"){
//other permission checking
}
}
}
Please note that it assumes you also customize the Authentication token to be MyAuthentication which includes userID. It also answers your 2nd concern is that you can customize the authentication process to return a customzied Authentication token which you can set the userId into it just after loading the user record for authentication. In this way , the userId will be stored inside the MyAuthentication which you do not need to query it again in the PermissionEvaluator.
Alternatively , you can also consider to directly express the authorisation logic in the @PreAuthorize without using hasPermission() for such simple case:
@PreAuthorize("#id == authentication.userId")
public EntityModel<Order> getOrders(@PathVariable Long id) {
}