【问题标题】:Resource level authorization in RESTful serviceRESTful 服务中的资源级授权
【发布时间】:2015-03-12 16:47:58
【问题描述】:

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

基本身份验证已启用,只有经过身份验证的用户才能访问该网址。

示例场景:

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

  • /users/1
  • /users/2

但期望User_1 应该可以访问/users/1 而不是/users/2 或其他用户ID。

问题: 如何在 RESTful 服务中做资源级授权?

注意:我正在使用 Jax-RS(使用 Apache CXF 实现)实现 RESTful,如果您可以使用 Jax-RS 进行解释,将会很有帮助。

-巴拉特

编辑:

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

举个例子,假设 /users/{id}/photos/{photoId} 是另一个资源 url。 User_1 应该被授予访问仅属于他的照片的权限。如果 photoId 2 属于 user_2,那么当请求 /users/1/photos/2 时,我们应该为 user_1 提供 http_404 错误代码。[由于 User_1 也是经过身份验证的用户,他可以调用 /users/2/photos/2,所以我们必须根据认证参数而不是通过资源url来识别用户id]

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

而不是SELECT * FROM PHOTO_TBL WHERE PHOTO_ID=2;

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

使用此资源正在交付属于特定用户的数据。 [应该有一种机制来防止客户端修改唯一ID,用于决定授权(在这种情况下是userId),因为所有请求都是STATELESS请求]

警告:每个查询都应该足够智能以了解安全问题并包含额外的连接。这是将安全逻辑绑定到每个业务功能的糟糕设计。

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

【问题讨论】:

  • 就像您在标签中指出的那样,这是一个通过身份验证的授权问题。这既可以滚动到应用程序中,也可以作为中间代理来实现,比较 URL 和身份验证标头中的用户 ID。
  • @Szocske:这是值得将其放入应用程序的地方。但是您可以使用 Spring AOP(当然还有 Spring Security)来简化它。唯一稍微棘手的一点是意识到这实际上不是基于角色的访问控制,因此 SpringSec 的 RBAC 支持不相关。 (唉,这就是最好的教程材料……)
  • 好的,现在我看到了关于图片 ID 的编辑,无论如何都需要加入 users 表。但是在这种情况下,无论如何都不需要 URL 中的用户 ID :-)
  • @Szocske:是的,url 中的 userId 不是必需的。
  • @Barath 你解决了这个问题吗?

标签: rest authorization jax-rs restful-authentication


【解决方案1】:

我建议不要在 url 中包含用户 ID(好像它被 Basic Auth 标头“限制”,那么您也可以让它由 Basic auth 标头“指定”)。这将降低引入直接对象引用漏洞的风险 - https://www.owasp.org/index.php/Top_10_2010-A4-Insecure_Direct_Object_References)

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

/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>;

对“Basic Auth Headers”的一个很好的解释:

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

【讨论】:

  • 您能解释一下什么是基本身份验证标头吗?
【解决方案2】:

JAX-RS specifies sub-resource 不是在方法中处理请求,而是将处理委托给其他对象 - 子资源。

使用子资源处理根资源就足够了,嵌套的资源也将得到保护。

在示例中,您可以看到 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() { /* ... */ }

}

【讨论】:

    猜你喜欢
    • 2014-08-29
    • 2012-11-18
    • 2011-07-07
    • 1970-01-01
    • 2016-05-21
    • 2014-07-09
    • 2020-10-08
    • 1970-01-01
    • 2017-11-10
    相关资源
    最近更新 更多