如何保护 RESTful API

Posted

技术标签:

【中文标题】如何保护 RESTful API【英文标题】:How to protect RESTful API 【发布时间】:2012-12-15 04:41:46 【问题描述】:

我一直在寻找一种方法来保护我的 RESTful API。这看起来很简单,但似乎没有那么简单。首先,我正在编写一个连接到 Play Framework 服务器的 ios 应用程序。这些都与 Google、Facebook、Twitter 或 LinkedIn 没有任何关系(我知道这很令人震惊)。哦,我目前的计划不需要自定义应用程序来使用我的 API,它暂时只是我的应用程序。

基本身份验证

看起来很简单的是一个基本的用户/通过 /auth 方法管理 cookie 会话。这可能会引起一些抱怨太简单或太弱,但大多数情况下它将身份转移到快速验证的会话密钥。我最初的设置是每天都使会话过期,但这导致 iOS 应用程序每天强制登录被证明是一件烦人的事情。

OAuth

我在 iOS 板上发布了一个问题,并收到了一个直截了当的 OAuth 指示。我对 OAuth 的研究开始了,但天哪,这太复杂了,而且似乎没有任何服务器端的例子......只是很多人抱怨它是多么令人沮丧。所有客户端示例都显示连接到 Google、Facebook、Twitter 和 LinkedIn。哦,快乐!

看了 Eran Hammer 对 OAuth1 和 OAuth2 的吐槽之后,继续下去似乎没有结果,他的 OZ 想法(看起来很干净)在 node.js 中还只是处于早期阶段。

问题

所以,我向广大 *** 社区提出的问题是……您如何保护您的 REST API?

【问题讨论】:

看看这个:***.com/questions/13784499/… 【参考方案1】:

我建议考虑大型参与者使用的方法,即 Amazon Web Services 或 Windows Azure - HMAC。虽然它在实施中并不舒适,但您可以看到它是值得信赖的技术。

一般的想法是在 iOS 中使用密钥对请求的部分(即标头)进行签名,并尝试在 Play 应用上重新计算它以验证请求是真实的且未被操纵。如果它不会失败,您可以(几乎)确定,这是由使用有效密钥的某人发送的。

查看Windows' document 以了解概念(我认为对于常见任务,您可以使用较少数量的元素用于签名)。

还有其他interesting post(基于AWS身份验证)更好地描述了整个过程。

编辑

当然,您应该意识到 iOS 中的身份验证和保护 API 请求是不同的事情,即使您的会话每 15 分钟到期一次,您也不能确定有人不会偷听它,然后将能够从外部发送虚假请求。签署每个请求应将风险降至最低。

另一方面,如果您准备明确的规则来签署请求并编写简短的文档(我什至建议您自己使用),您可以将其交付给其他开发人员,他'将能够在(几乎)任何支持 SHA256 的平台中实现它,因此您将准备好从 3 rd 方应用程序中使用的 API - 如果您决定在未来发布它。

【讨论】:

感谢您指导 HMAC。我已经阅读了您在此处发布之前提到的 AWS 帖子。它最终类似于 OAuth 2-legged,但由于某种原因更容易理解。但是......我只是不禁想知道这与 SSL 有什么不同,它向我隐藏了所有的复杂性。通过 SSL 进行用户/传递会话会更好吗?这样做的缺点是什么?其他人最终会采取什么措施来避免 OAuth 和 HMAC 带来的复杂性? 这只是口味问题,使用 SSL 您需要在 Play 应用程序之上添加前端 HTTP 服务器,因为 Play 2.x 中没有原生 SSL 支持,您还需要购买SSL 证书并每年更新。 HMAC 签名方法更加“独立”,我会特别选择 API 相对较小的临时应用程序。我实际上还需要添加一件事,描述的 HMAC 提供签名消息,但不加密其正文,因此专用于身份验证,但不能确保完全隐私,如果要发送敏感数据,请小心。 我是这个主题的新手,虽然我阅读了链接,但我仍然需要澄清(也许其他人会这样做)。在我看来,使用 HMAC,您可以使用服务器对客户端应用程序进行身份验证,但您没有获得任何基于用户的授权。我错了吗?相关:我认为我理解 OAuth 提供身份验证和授权功能。我也错了吗?【参考方案2】:

由于 Play Framework 是 Java 语言,您可以使用 Apache Shiro

我还没有使用它..(虽然我打算)所以我不知道它是否是最好的选择。

【讨论】:

【参考方案3】:

只需做一些简单的事情,通过 HTTPS 在自定义标头中发送授权码/密码。

【讨论】:

这也是我一直想知道的。这样做有什么坏处?【参考方案4】:

所以基本身份验证方法的唯一问题是用户必须每天登录?为什么不为用户提供在设备上保存用户名/密码的选项?这样他就可以在安全性和便利性之间做出选择。

【讨论】:

这就是我到目前为止所做的,将用户/密码存储在钥匙串中以便在后台重播。

以上是关于如何保护 RESTful API的主要内容,如果未能解决你的问题,请参考以下文章

在过滤的 API Restful 资源中添加子类别

如何保护 RESTful API

如何使用 Flask-USER 管理保护 Flask-RESTful?

如何保护移动和 AJAX 调用的 JSON RESTful API?

如何保护简单的 Node.js RESTful API

保护 RESTful Web 服务 URL [重复]