问题
I would like to use SpEL to handle method level security. I run into an issue where the data passed to the method is not enough to determine if a user has access. Here is an example
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
@ResponseStatus(HttpStatus.NO_CONTENT)
@PreAuthorize("@securityService.isAllowedAccessByCurrentUser(#.id)")
public void delete(@PathVariable("id") final Long id) {
service.delete(id);
}
Here, the id variable is the ID of some object. To get the owner ID of the object (which is what i want to pass in the spel expression), I would need to do something like:
service.findOne(id).getUser().getId();
How can I get that ID and use it in the SpEL expression?
回答1:
Why need to so complicated? You can simply create another method to specifically check if the current user can delete an object given that object Id and make the @PreAuthorize
refer to this method:
@Service
public class SecurityService{
@Autowired
private Service service
boolean isAllowToDeleteSomeObject(Long objectId){
SomeObject anObject = service.findOne(objectId);
//You should able to get the current user Id by SecurityContextHolder.getContext().getAuthentication().
//getCurrentUserId() simply encapsulate such codes for convenient.
Long currentUserId = getCurrentUserId();
if(anObject.getUser().getId().equals(currentUserId)){
return true;
}else{
return false;
}
}
}
Then you can refer to this method in SpEL:
@PreAuthorize("@securityService.isAllowToDeleteSomeObject(#.id)")
public void delete(@PathVariable("id") final Long id) {
}
来源:https://stackoverflow.com/questions/56956012/need-data-from-database-for-use-in-spel-method-level-security