Search code examples
javaspringspring-mvcspring-securityacl

Without using Spring ACL, implementing a method level security check based on "creator" of an entity


Like many others have noted, the ACL seems like overkill for executing such a conceptually simple thing in a case like this.

I am looking for a simple implementation of the following scenario in Spring Security:

I have a method in a controller which handles a delete request for an event entity. I need the @PreAuthorize expression that will check to make sure that the ID of the user submitting the request matches the ID of the owner of the request. Perhaps through an Event.getOwner().getId() method.

How would this look? Thanks.

I'm thinking something like. The following method in the Event controller:

 @PreAuthorize("#event.getOwner().getId() == authentication.id")
 public void delete(@PathVariable("id") final Long id, @RequestBody final Event event) {
    repo.delete(id, event);
}

And if this is the correct use, where does #event come from? In other words, what is signified by the '#'? I ask because at this point we are in the controller, so, which Event is #event referring to?


Solution

  • Your idea is not safe. It requires that the event information including owner is sent as request body in the delete request. With this the client can spoof the owner to be of the current user instead of the actual owner.

    Assuming that id is the unique id of an event, I would suggest something like the following as a minimal solution:

    @RequestMapping(value="/{id}", method=RequestMethod.DELETE)
    @PreAuthorize("@repo.getOwnerOfEvent(#id) == authentication.name")
    public void delete(@PathVariable("id") final Long id) {
        repo.deleteEvent(id);
    }
    

    The above snippet requires a bean named "repo" that contains the method:

    /**
     * Returns the owner username of the event with the specified id.
     */
    String getOwnerOfEvent(long id);