Resource level authorization in RESTful service

2019-03-13 05:10发布

Let /users/{id} be a resource url in RESTful service.

Basic authentication is enabled and only authenticated users are allowed to access the url.

Example Scenario:

User_1 & User_2 are authenticated users with userId 1 & 2. Since both are authenticated, both of them are having access to,

  • /users/1
  • /users/2

But the expectation is User_1 should have access to /users/1 and not to /users/2 or other userId.

Question: How to do resource level authorization in RESTful services?

Note: I am implementing RESTful using Jax-RS (with Apache CXF implementation), helpful if you could explain with Jax-RS.

-Barath

Edit:

As Donal mentioned, I am not looking for role based authorization rather resource level authorization.

To give an example, lets say /users/{id}/photos/{photoId} be another resource url. User_1 should be given access to the photos belong to him only. If photoId of 2 belonging to user_2, then we should give http_404 error code for user_1 when a request /users/1/photos/2 is requested.[Since User_1 is also authenticated user he can invoke /users/2/photos/2, so we must identify the user id based on authentication parameters than via resource url]

Only solution I can think of is, include the unique id which determines the authorization in each query like,

Instead of SELECT * FROM PHOTO_TBL WHERE PHOTO_ID=2;

use SELECT * FROM PHOTO_TBL, USER_TBL WHERE PHOTO_ID=2 AND USER_ID=1 AND USER_ID=PHOTO_ID;

with this resources are delivering data that belongs to specific user. [There should be a mechanism to prevent the modification of the unique id in client side which is used to decide on authorization(userId in this case), since all requests are STATELESS request]

Caveat: Each and every query should be intelligent enough to understand the security concerns and include extra join. This is a bad design to tie up security logic to every business function.

I am yet to look into Spring security and how it can be used in this use case.

2条回答
爷的心禁止访问
2楼-- · 2019-03-13 05:38

JAX-RS specifies sub-resource where instead of handling request in a method, processing is delegated to other object - sub-resource.

Using sub-resources it's enought to take care of the root resource and nested ones will be secured as well.

In the example you can see UserResource and all it's sub-resources available only to authorized user.

@Path("/user/{userId}")
public class UserResource {

  private final String userId;

  public UserResource(@PathParam("userId") String userId, @Context SecurityContext securityContext) {
    this.userId = userId;

    boolean authorized = /* authorization code */;

    if (!authorized) { throw new WebApplicationException(Status.UNAUTHORIZED); }
  }

  @Path("photo")
  public PhotoResource getPhotoResource() {
    return new PhotoResource(userId);
  }

}

public class PhotoResource {

  private final String userId;

  public PhotoResource(String userId) {
    this.userId = userId;
  }

  @GET
  public Response listAll() { /* ... */ }

  @GET
  @Path("{photoId}")
  public Response present() { /* ... */ }

}
查看更多
做个烂人
3楼-- · 2019-03-13 05:50

I would recommend not having the user id in the url (as if it's being 'limited' by a Basic Auth header then you may as well just have it 'specified' by the Basic auth header). This will reduce the risk of introducing a Direct Object Reference Vulnerability - https://www.owasp.org/index.php/Top_10_2010-A4-Insecure_Direct_Object_References)

In this case you could have one of the following urls:

/users/CURRENT
/me

As photos is a sub resource then you could just create the photos with a "sequence number" within the user. In a sql database this would mean having a "compound key" across both user and photo columns.

/users/CURRENT/photo/{user_photo_seq}
/me/photo/{user_photo_seq}

Your SQL would then look something like:

SELECT * FROM PHOTO_TBL WHERE USER_ID=<BasicAuthUsername> AND PHOTO_ID=<path param value>;

A good explanation of "Basic Auth Headers":

http://en.wikipedia.org/wiki/Basic_access_authentication

查看更多
登录 后发表回答