15

我知道这可能是一个古老的问题,但是......是否有任何最佳实践来保护客户端机密以在 AngularJS 应用程序中执行 OAuth2 身份验证?我一直在绞尽脑汁想出一种解决方案,从现代风格的 Web 应用程序中提供对 API 的真正安全访问(它们不一定是 AngularJS。)根据我的经验,添加抽象层和混淆层确实不行任何可以提高安全性的东西……它们只会让任何潜在的黑客更难以破解安全蛋(但是他们中的许多人更喜欢一个好的挑战,所以你真正要做的只是让黑客更有趣。)

除了明显无效的解决方案(例如代码的混淆和卷积等)之外,在现代 Web 应用程序中是否有保护客户端机密的最佳实践?我知道这些问题是由桌面客户端应用程序引起的,而且我不相信除了“最好混淆,这会减慢黑客的速度”之外,还有其他解决方案。我们与网络应用程序在同一条船上吗?这个问题没有真正的解决方案吗?

如果没有解决方案……使用 OAuth 保护 REST API 真的有任何意义吗?

4

2 回答 2

23

请记住,OAuth不是关于防止假冒,而是更多关于保护凭据。第三方为您验证了用户的身份,而不会暴露用户的凭据。由于代币不是凭证,黑客可以造成的伤害量和他的行动窗口是有限的。

但是对于您的应用程序而言, OAuth本质上并不比常规用户名/密码身份验证更安全。在客户端应用程序上,您的所有代码都可供全世界查看!正如您所提到的,客户端加密是一个有问题的策略。


虽然没有既定的保护客户互动的最佳实践,但这里有一些方法可以最大限度地减少您的风险:

1)SSL:银弹?也许。您在站点和请求中使用SSL的次数越多,用户的请求就越安全。老实说,我相信所有特权请求都应该由加密请求发出。

2) 令牌寿命短:令牌的寿命越短,嗅探它的激励/优势就越小。

OAuth 2.0 通过将身份验证令牌交换为身份验证令牌的刷新令牌来创建身份验证之外的持续聊天。作为开发人员,您现在正在开发一个聊天应用程序,该应用程序执行很多“你的令牌是什么,这是另一个令牌,向我要一个令牌,这是你的新令牌......所以你想要什么?” ……“哎呀,时间到了,你的刷新令牌呢?”

如果这听起来很痛苦,那确实是。OAuth 2.0 旨在使开发人员的流程更轻松。但重要的一点是,代币的寿命越短,黑客就越难维护欺诈身份。 刷新令牌参考

3) 加强你的领域:想要减少嗅探者滥用你盔甲缝隙的机会吗?不允许跨域请求!

当然,我们经常有分布式环境。但是,如果您的 Facade 位于客户的域中,那么您的曝光就会减少(单词选择有问题)。

强迫黑客使用你的域名,限制他们的创造力。

4) 使用 3rd 方 API 尽可能多地维护您的访问权限: GoogleFacebook API 和服务已经过单元测试、实战测试和演进。你越能依靠他们来维护你的用户的身份,你做的工作就越少,你获得的机会就越少。

5)检查IP地址:几乎任何东西都可以伪造,但黑客必须知道IP地址是你验证的一部分。这是所有实践中最不可靠的,但结合 1,2 或更多,黑客可以利用的差距越来越小,努力的回报也逐渐消失。

6)使用“秘密”或第二个参数:你可以传递你的用户而不是令牌。您可以传递自己的 Alter-Token。

假设它是一个来回传递的 ID 数据。以不明显的方式命名参数。将其设为数字​​(例如年龄、身高、地址)。重要的一点是,您的黑客对对方的要求知之甚少或一无所知!

您可以通过具有 3 个作为安全性的参数来抛出一个严重的活动扳手。

7)不要给出错误信息来通知黑客他们已经被抓到了。给出超时消息而不是“知道了!” 如果入侵者没有意识到欺诈行为被抓住了,他们也不会适应。


我不能说太多—— SSL 省去了很多麻烦。

注意:我见过的所有客户端提供商都允许访问他们的 API 而不会暴露 Secret。秘密不应该暴露在客户端上。

  • 客户端上暴露的任何数据都可以闪烁
  • 您使用的任何加密算法都将在客户端上公开。
于 2014-07-07T23:57:34.063 回答
3

我来这里是为了寻找这个问题的答案——如何在 SPA 中处理秘密/ID。我想出了自己的解决方案,将秘密隐藏在服务器中,但我想确认我所做的是最佳实践。因此,由于答案避免了这种情况,我将解释我的流程,希望它能帮助任何人。

我们的架构——我们有一个 ruby​​ 服务器作为 api 服务器和一个快速服务器为 Angular 应用程序提供服务。

通常所有的通信都是通过 api 简单地以 RESTfully 方式完成的,因此节点服务器只是提供静态文件,而不是真正做很多事情。

由于我们正在实施登录/注册流程,所以我遇到了 - 对我来说是新的 - OAuth 2.0 如何处理事情的流程。

在我们向服务器发出任何请求并且服务器会认真对待我们之前,我们需要让自己获得 Bearer 令牌。我选择将其实现为节点端点,从而将客户端密码隐藏在节点服务器本身内。

所以我们的客户已经输入了他们所有的多汁数据,并准备成为我们应用程序中的用户,他们点击了提交按钮。

  1. 该应用程序向节点服务器发出请求,以获取我们可以用作承载者的美味令牌。我选择将客户端 ID 作为 GET 请求查询参数传递。首先,我在节点服务器中同时拥有客户端 ID 和机密,但感觉 ID 可以/应该在客户端上。所以我就这样走了。

  2. 节点服务器通过 GET 请求接收客户端 ID,然后继续将 POST 发送到主机(ruby api)。构造 url + 授权类型 + 客户端 ID + 客户端密码。从而向世界隐藏实施。

  3. ruby 服务器返回一个令牌供我们使用,然后我们将其返回给初始化注册请求的客户端。

  4. SPA 现在有一个不记名令牌,我们可以在注册请求的标头中使用它。

从而完成我们的流程,并拥有一个隐藏在世界上的古老秘密。

由于我们有一个具有一定寿命的令牌,我们还有一个请求错误拦截器,它将捕获已过期的令牌,从而发出新的令牌请求,然后重新触发失败的调用。

我选择在 Angular 方面使用这个 lib for users flow。

https://github.com/sahat/satellizer

它是一个超级方便的库,每次我们希望应用程序通过电子邮件/密码以及通过 oauth 进行身份验证时都必须编写所有无聊的样板代码......非常方便。

因此,由于这是我自己对如何做这些事情的解释 - 请提供反馈。

于 2016-03-14T08:10:14.117 回答