授权依赖的REST API

时间:2014-01-07 11:38:47

标签: api rest authorization

作为服务器REST API设计的一部分我正在考虑我希望能够返回以客户端授权级别为条件的数据。什么是推荐的方法来完成它仍然称之为一个API?更具体地说,请考虑以下关于图书访问API的示例:

HTTP GET /library/books/{book-name}
  1. 任何经过身份验证的客户端都应该能够获取该书的(JSON)数据,例如:

    {  “书”:     {“book-name”:“abc”,“author”:“someone”} }

  2. 但是经过身份验证的客户端的特定子集也应该能够获得:

    {  “书”:     {“book-name”:“abc”,“author”:“someone”},     “私人信息”:     {“book-status”:“on-loan”,“price”:“$ 20”} }

  3. 对于给定的图书,任何经过适当授权的客户也可以通过直接的HTTP GET / library / books / {book-name} / private-info访问“私人信息”。

    现在,假设有一个合适的客户端身份验证方案,我不禁认为上面的HTTP GET / library / books / {book-name}实际上看起来像两个API,区别于服务器上的授权状态认证。这似乎不是非常RESTful。

    也许最好保持基本GET book API对所有人都没有任何“私人信息”,同时提供授权客户端只访问私有信息URI并返回403给所有其他人?

    这种类型的条件数据访问通常如何使用REST API处理?

2 个答案:

答案 0 :(得分:1)

您的方法没有任何内在错误 - 根据用户的授权隐藏信息是很有意义的。 REST没有说明这一点 - 资源的表示可能取决于用户授权,月相或你能想到的其他任何东西。

如果将私有信息提取到单独的资源,您可以改进缓存。在这种情况下,您将拥有/ library / books / {book-name}的一些相当静态的内容,可以在客户端缓存。那么你将拥有/ library / books / {book-name} / private-info,这将更加易变,并且不依赖于用户 - 因此不易安置。

在此基础上,您可以在原始资源中包含指向私人信息的链接:

{
  Title: "A book",
  Author: "...",
  PrivateInfoLink: "http://your-api.com/library/books/{book-name}/private-info"
}

这样做的好处是双重的:

1)如果客户端无法访问私人信息,服务器可以省略链接,从而使客户端免于不必要的往返(不)获取私人信息。

2)如果稍后需要,服务器可以自由更改私人信息URL(例如,它可以是基于用户授权的不同URL)。

如果您想了解有关超媒体优势的更多信息,请尝试以下方法:http://soabits.blogspot.dk/2013/12/selling-benefits-of-hypermedia.html

答案 1 :(得分:1)

我最近回答了一个类似的问题。你可以找到我的答案here

底线是:您应该尝试将业务逻辑与授权逻辑始终分开。这意味着您要外部授权。有几种方法可以做到这一点。

在您的特定情况下,想象一下敏感字段列表,只有一部分客户端可以查看随时间的变化,这可能需要重写您的API。如果将授权逻辑与业务逻辑(API)分离,则可以轻松更新授权逻辑,而无需重写任何代码。这称为外化授权管理(请参阅此主题的Gartner paper。)

作为我日常工作的一部分,我使用XACML帮助客户保护API和Web服务。最佳做法始终是将问题分开。