“私有” REST API 的安全性

23

我目前正在开发一个网络应用程序,它由一个前端组成,使用我们编写的REST API来显示和交互数据。唯一使用API的是我们的前端网站,以及我们将开发的移动应用程序。

我已经阅读了很多有关OAuth是保护API的理想机制的文章,现在我开始对它的工作原理有了很好的理解。

我的问题是,既然我永远不会将API授权给第三方客户端,OAuth真的必要吗?是否有任何优势?此外,由于后端只是API,没有用户可以从中进行身份验证的网关(就像如果您使用Twitter API编写应用程序时,当用户验证时,他们将被定向到Twitter页面以授予访问权限,然后重定向回客户端)。

我不太确定该走哪个方向。看起来必须有某种方法介于http身份验证和OAuth之间,适用于这种情况,但我还是不明白。

4个回答

1
从我的角度来看,支持OAuth而不是其他选项的情况之一是与不受信任的客户端(无论是您自己开发的还是第三方开发的)一起工作。
“什么是不受信任的客户端?” 请从处理授予对您的API访问权限的凭据的人的角度考虑。
例如,您的Web应用程序可以以两种方式与您的API交互:
1. 您的Web应用程序服务器端与您的API通信。您的Web应用程序服务器是受信任的客户端,因为访问API的凭据只能被访问该服务器的人员访问...即您和您的团队。您可以使用client_id和client_secret验证您的Web应用程序服务器。
2. 您可能希望直接从运行在最终用户浏览器上的JavaScript的Web应用程序客户端调用您的API。最终用户的浏览器是不受信任的客户端。如果将凭据传递到浏览器中,任何人都可以检查JavaScript代码并窃取您的凭据。
  • 第三方原生应用程序也是不受信任的。使用您的 API 的恶意开发人员可能会保存您平台的最终用户的凭据。

  • 您的原生应用程序是可信客户端,可以通过简单的用户名、密码和标识您的应用程序的客户端 ID 来管理身份验证。

OAuth 如何帮助? OAuth 授权码隐式 授权可以帮助您解决此问题。这些流程仅适用于支持重定向的客户端,例如浏览器。并且允许您对不受信任的客户端和用户进行身份验证,以获得对您的授权服务器、资源服务器和 API 的访问权限,而不会暴露凭据。请查看 RFC 以了解其操作方式。

OAuth 的好处在于它不仅支持这些基于重定向的身份验证流程,还支持客户端凭据授权和用户凭据授权。因此,OAuth 授权服务器将涵盖所有情况。


1

如果你考虑要自己构建OAuth 2.0,那么它最初似乎很麻烦,但大多数编程语言都有一些非常可靠的OAuth 2.0设置,你可以根据需要进行调整。如果你使用像Laravel或RoR这样的框架,那么这几乎不需要什么工作。

如果你不想像帖子中建议的那样重定向用户,那么请忽略其他评论和回答,这些评论和回答谈论了两个腿流。你可以使用client_credentials授权类型,只需提供应用程序的客户端ID和密钥即可获得访问令牌,这非常简单易行。

我会问有多私密,因为如果只有在后端内部交互的系统并且没有与外部世界互动,那么你可能可以将其保持开放,并依靠网络来保护它(VPN/Firewall)。

但如果它是“我们的iPhone应用程序使用它”这种私有意义上的,那么你肯定想选择OAuth 2.0或类似的东西。


0

移动设备与API层通信应使用Oauth。

然而,在Web UI层到中间层的访问(机器到机器)中,使用Oauth没有任何好处。

另一方面,存在一些潜在问题:

  1. 管理访问令牌的过期时间会变得很麻烦。考虑到您的UI必须在集群中的多个节点上缓存访问令牌,并在其过期时进行刷新,而且UI层正在不时地与后端协商安全性,这将需要额外的时间。

  2. 在两个步骤的Oauth(OAuth Client Credential,如v2.0中所示)中不支持任何加密。因此,您仍然需要向服务器发送密钥和密码以获取访问令牌。

  3. 后端必须实现发放访问令牌、刷新令牌、验证访问令牌等功能,但没有任何显著的好处。


0

你可能想要使用2-legged OAuth。它基本上是对共享密钥进行哈希处理,但你有不必自己编写代码的优势。

这里有一个相关的问题:寻找关于2-legged OAuth的信息


好的。那么这个想法就是通过使用用户名和密码以及使用私钥的签名来处理API登录,授予一个令牌,然后在未来的调用中使用令牌和签名来完成会话的剩余部分? - brandonvvv
在您的情况下,私钥可以是用户的密码。在http://code.google.com/p/oauth-php/wiki/ConsumerHowTo#Two-legged_OAuth的示例中,$key将是用户名,$secret将是密码。 - jbowes
所以如果我理解正确,在这种情况下,每个请求都必须提交用户名和密码? - brandonvvv
是的,尽管密码不是以明文形式发送的;它被用于哈希请求URL。这比使用基本身份验证更好,因为使用基本身份验证时,第三方可以嗅探标头并使用相同的标头请求不同的URL,而如果他们尝试使用OAuth标头进行此操作,则服务器端的身份验证将失败。 - jbowes
1
但这意味着我需要在客户服务器上以明文形式存储所有的用户名和密码,以便用于签名。 - brandonvvv
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接