1

There are many good resources and literature on how to set up a a JAX-RS API. However, I have yet to find any resource that properly describes how to do security restrictions towards specific resources and methods. For example, given a resource PictureResource, only the uploader of the picture (and an admin) should be able to delete or change properties related to the picture, while anyone should be able to view the picture. The admin restriction is fine as it can be solved by roles, however the uploader would depend on the context of the call. A token identifying the user would then describe who is making the call. This can be solved through a ContainerRequestFilter.

@Path("pictures/{pictureId}")
public class PictureResource {

    @GET
    public Response getPicture(@PathParam("pictureId") final int pictureId) {
        // Get the picture, available for all users.
    }

    @DELETE
    public Response deletePicture(@PathParam("pictureId") final int pictureId) {
        // Delete the picture, only available for the uploader of the picture and admins.
    }

    // ...
}

What would be the JAX-RS way of solving this issue? I'm assuming this can be solved by annotations, but is is rather vague to me how to do this. Would another approach be to dynamically assign the user a pictureOwnerRole depending on the context of the call?

Martin
  • 2,606
  • 4
  • 24
  • 38
  • Have you seen [this](http://stackoverflow.com/q/26777083/2587435) – Paul Samsotha Nov 13 '15 at 11:07
  • That post is pretty much the second link I got in my post but more elaborated. In my case, I want to restrict based on the context of the call. For example, the user that is signed in AND is the uploader of the picture is allowed to delete the picture. – Martin Nov 13 '15 at 11:14
  • Since you know the user who is calling your endpoints and who uploaded the picture, I think a simple `if` condition in your method will do the trick. And, if the user is not allowed perform the action, just throw a [`ForbiddenException`](http://docs.oracle.com/javaee/7/api/javax/ws/rs/ForbiddenException.html). – cassiomolin Nov 13 '15 at 11:17
  • SecurityContext & Principal are most likely what you'd use: https://jersey.java.net/documentation/latest/security.html / http://stackoverflow.com/a/5472279/995891 `Principal` can be a custom class representing the user and you can inject it into your method and then check whether that user is allowed yourself. That check needs custom logic since resources don't a have natural ownership. You could also make an Authorization filter http://blog.dejavu.sk/2014/02/04/filtering-jax-rs-entities-with-standard-security-annotations/ – zapl Nov 13 '15 at 11:22
  • @CássioMazzochiMolin, I am aware of this but it is my last resort to this problem as I really do want to avoid mixing business logic and validation logic to the greatest extent possible. – Martin Nov 13 '15 at 11:22
  • I would keep it simple and just use a framework like Spring Security. It maintains the logged in user for you through the use of cookies, and on request the state of the user is extracted from the cookie, which you can use to set up authorization. Security it tough to implement yourself in a web application and get it right. A simple API where only API clients are interacting is easy to implement. But once you start mixing web applications and end users, it get a little more complicated. Personally i would recommend using an established framework – Paul Samsotha Nov 13 '15 at 11:24

1 Answers1

2

The problem is discrete resource access control. You need a standard way to describe the resource being accessed in terms of ownership. Who owns the resource, and who has been granted scoped authority over it.

The problem is that this is very domain specific. Resource grouping and ownership requires the ability to lookup a resource instance or associated metadata and determine ownership/access requirements.

I don't know of any security frameworks that provide a standard framework or annotation for this.

You could place pictures into a directory structure and use directory access control to determine what users have what access to the resources.

Something like @Secured("ownerDecider=PictureInspector.class") would be how I would approach it. The AccessDecisionVoter or AfterInvocationProvider in spring security could then use the provided strategy for discerning ownership, and restrict access accordingly.

dds
  • 2,335
  • 1
  • 31
  • 45
Ahkilleux
  • 21
  • 4