RESTful服务中的资源级授权

RESTful服务中的资源级授权,rest,authorization,jax-rs,restful-authentication,Rest,Authorization,Jax Rs,Restful Authentication,让/users/{id}成为RESTful服务中的资源url 已启用基本身份验证,并且仅允许经过身份验证的用户访问url 示例场景: User_1和User_2是用户ID为1和2的经过身份验证的用户。 由于两者都经过身份验证,因此都可以访问 /users/1 /users/2 但是期望是用户1应该能够访问/users/1,而不是/users/2或其他用户ID 问题: 如何在RESTful服务中进行资源级授权 注意:我正在使用Jax-RS实现RESTful(使用ApacheCXF实现),如果您

/users/{id}
成为RESTful服务中的资源url

已启用基本身份验证,并且仅允许经过身份验证的用户访问url

示例场景:

User_1
User_2
是用户ID为1和2的经过身份验证的用户。 由于两者都经过身份验证,因此都可以访问

  • /users/1
  • /users/2
但是期望是
用户1
应该能够访问
/users/1
,而不是
/users/2
或其他用户ID

问题: 如何在RESTful服务中进行资源级授权

注意:我正在使用Jax-RS实现RESTful(使用ApacheCXF实现),如果您可以使用Jax-RS进行解释,这将非常有用

-巴拉斯

编辑:

正如Donal提到的,我不是在寻找基于角色的授权,而是资源级别的授权

举个例子,假设/users/{id}/photos/{photoId}是另一个资源url。用户_1只能访问属于他的照片。如果photoId 2属于用户_2,那么当请求/users/1/photos/2时,我们应该为用户_1提供http_404错误代码。[由于用户_1也是经过身份验证的用户,他可以调用/users/2/photos/2,因此我们必须基于身份验证参数而不是通过资源url来识别用户id]

我能想到的唯一解决方案是,在每个查询中包括确定授权的唯一id,如

而不是
从PHOTO_TBL中选择*FROM PHOTO_ID=2

使用
SELECT*FROM PHOTO_TBL,USER_TBL,其中PHOTO_ID=2,USER_ID=1,USER_ID=PHOTO_ID

有了这些资源,我们可以交付属于特定用户的数据。[由于所有请求都是无状态请求,因此应该有一种机制来防止修改客户端中用于决定授权的唯一id(在本例中为用户id)。]

注意事项:每个查询都应该足够智能,能够理解安全问题并包含额外的连接。将安全逻辑与每个业务功能捆绑在一起是一个糟糕的设计


我还没有研究Spring安全性以及如何在这个用例中使用它。

我建议不要在url中使用用户id(如果它受到基本身份验证头的“限制”,那么您也可以通过基本身份验证头“指定”)。这将降低引入直接对象引用漏洞的风险-)

在这种情况下,您可以使用以下URL之一:

/users/CURRENT
/me
因为照片是一个子资源,所以您可以在用户中创建带有“序列号”的照片。在sql数据库中,这意味着在用户列和照片列中都有一个“复合键”

/users/CURRENT/photo/{user_photo_seq}
/me/photo/{user_photo_seq}
您的SQL将如下所示:

SELECT * FROM PHOTO_TBL WHERE USER_ID=<BasicAuthUsername> AND PHOTO_ID=<path param value>;
从PHOTO_TBL中选择*其中USER_ID=和PHOTO_ID=;
对“基本身份验证头”的一个很好的解释:

其中,处理不是在方法中处理请求,而是委托给其他对象子资源

使用子资源就足以保护根资源和嵌套资源

在本例中,您可以看到UserResource及其所有子资源仅对授权用户可用

@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() { /* ... */ }

}

正如您在标记中所注意到的,这是一个经过身份验证的授权问题。这可以在应用程序中实现,也可以作为一个中介代理来比较URL和身份验证头中的用户ID。@Szocske:这是值得在应用程序中使用的地方。但是您可以使用SpringAOP(当然还有SpringSecurity)使其更简单。唯一稍微有点棘手的一点是认识到这实际上不是基于角色的访问控制,因此SpringSec的RBAC支持与此无关。(唉,这就是最好的教程材料的内容…)好的,现在我看到了关于图片ID的编辑,它无论如何都需要连接到用户表。但是,在这种情况下,URL中几乎不需要用户id:-)@Szocske:是的,URL中不需要用户id。@Barath您解决了这个问题吗?您能解释一下基本的身份验证头是什么吗?