保证REST API的安全,同时又不重新发明轮子

在设计REST API时,通常先验证用户身份?

我正在寻找的典型用例是:

  • 用户想要获取数据。 当然很酷,我们喜欢分享! 获取一个公共API密钥并阅读!
  • 用户想要存储/更新数据......哇等等! 你是谁,你能做到吗?
  • 我想构建一次,并允许说一个Web应用程序,一个Android应用程序或iPhone应用程序来使用它。

    REST API似乎是这样的需求的合理选择

    为了说明我的问题,我将使用一个简单的例子。

    我有一个数据库中的项目,它有一个评分属性(整数1到5)。

    如果我正确理解REST,我会使用我选择的语言实现GET请求,该语言返回csv,xml或json,如下所示:

    http://example.com/product/getrating/{id}/
    

    假设我们选择我们返回的JSON:

    {
      "id": "1",
      "name": "widget1",
      "attributes": { "rating": {"type":"int", "value":4} }
    }
    

    这对于面向公众的API来说很好。 我得到那部分。

    我有很多问题,我如何将它与安全模型结合起来? 我习惯了网络应用程序的安全性,我有一个会话状态随时可以识别我的用户,所以我可以控制他们可以做什么,无论他们决定发送给我什么。 据我了解,这不是RESTful,所以在这种情况下将是一个不好的解决方案。

    我会尝试使用另一个使用相同项目/评级的示例。

    如果用户“JOE”希望评级添加到项目

    这可以使用:

    http://example.com/product/addrating/{id}/{givenRating}/
    

    此时我想存储数据,说“JOE”给出的产品{id}的评分为{givenRating}。

    问:我如何知道请求来自“JOE”而不是“BOB”。

    此外,如果是为了更加敏感的数据,比如用户的电话号码呢?

    到目前为止我所得到的是:

    1)使用HTTP的内置功能在每个请求进行身份验证,无论是纯HTTP还是HTTPS。

    这意味着每个请求现在都采取以下形式:

    https://joe:joepassword@example.com/product/addrating/{id}/{givenRating}/
    

    2)使用像Amazon S3那样的私钥和公钥的方法:http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/

    3)无论如何都要使用cookie并打破REST的无状态部分。

    第二种方法对我来说似乎更好,但我仍然想知道我是否真的必须重新发明这整个事情? 散列,存储,生成密钥等都由我自己?

    这听起来很像在典型的Web应用程序中使用会话并自己重写整个堆栈,通常我的意思是“你做错了”,特别是在处理安全性时。

    编辑:我想我应该也提到了OAuth。


    5年后编辑

    使用OAuth2!

    以前的版本

    不,绝对不需要使用cookie。 它不如HTTP摘要,OAuth或亚马逊的AWS(这不难复制)安全一半。

    您应该查看cookie的方式是,它与Basic / Digest / OAuth /无论哪一个都是相同的身份验证令牌,但不太合适。

    不过,只要会话cookie的内容不会影响您从服务器返回的资源内容,我并不认为使用cookie本身违背RESTful原则。

    饼干是邪恶的,停止使用它们。


    不要担心“RESTful”,担心安全问题。 以下是我的做法:

    第1步:用户使用凭证访问身份验证服务。

    步骤2:如果凭证签出,返回一个指纹,会话ID等等,并将它们弹出到共享内存中以便稍后快速检索,或者如果您不介意将几毫秒添加到Web服务周转时间,请使用数据库。

    步骤3:将入口点调用添加到每个Web服务脚本的顶部,以验证每个Web服务请求的指纹和会话ID。

    步骤4:如果指纹和会话ID无效或超时重定向到认证。

    读这个:

    RESTful认证


    3年后编辑

    我完全同意Evert,使用HTTPS使用OAuth2,并且不要重新发明轮子! :-)

    通过更简单的REST API - 不适用于第三方客户端--JSON Web Tokens也可以。

    以前的版本

    无论如何都要使用cookie并打破REST的无状态部分。

    不要使用会话,使用会话你的REST服务将不会很好的扩展......这里有两种状态:应用程序状态(或客户端状态或会话)和资源状态。 应用程序状态包含会话数据,并由REST客户端维护。 资源状态包含资源属性和关系,并由REST服务维护。 你可以很容易地决定一个特定的变量是应用程序状态还是资源状态的一部分。 如果数据量随着活动会话的数量而增加,则它属于应用程序状态。 因此,例如,当前会话的用户身份属于应用程序状态,但用户列表或用户权限属于资源状态。

    因此,REST客户端应该存储识别因子并将其发送给每个请求。 不要将REST客户端与HTTP客户端混淆。 他们不一样。 如果REST客户端使用curl,它也可以位于服务器端,或者它可以创建例如服务器端http only cookie,它可以通过CORS与REST服务共享。 唯一重要的是REST服务必须通过每个请求进行身份验证,因此您必须随每个请求一起发送凭据(用户名,密码)。

  • 如果您编写客户端REST客户端,则可以使用SSL + HTTP身份验证完成此操作。 在这种情况下,您可以在服务器上创建credentials -> (identity, permissions)缓存,以便更快地进行身份验证。 请注意,如果您清除缓存并且用户发送相同的请求,则它们将得到相同的响应,只需要更长的时间。 您可以将其与会话进行比较:如果您清除会话存储,则用户将得到一个status: 401 unauthorized响应...
  • 如果您编写服务器端REST客户端,并通过curl将标识因子发送到REST服务,则您有2种选择。 您也可以使用http auth,或者您可以在REST客户端中使用会话管理器,但不能在REST服务中使用。
  • 如果有人不信任地写入REST客户端,那么您必须编写一个应用程序来验证用户身份,并为他们提供可用性,以决定他们是否要将权限授予不同的客户端。 Oauth是一个已经存在的解决方案。 Oauth1更安全,oauth2不太安全,但更简单,我想这个问题还有其他几个解决方案......你不必重新创建这个。 有完整的使用oauth的认证和授权解决方案,例如:使用oauth身份认证服务器。
  • 饼干不一定是坏的。 您可以以RESTful方式使用它们,直到它们保持客户端状态并且服务仅保持资源状态。 例如,您可以将购物车或首选分页设置存储在Cookie中...

    链接地址: http://www.djcxy.com/p/21959.html

    上一篇: Securing REST API without reinventing the wheel

    下一篇: How to secure RESTful web services?