在AngularJS应用程序中保护OAuth clientId / clientSecret

时间:2014-05-27 18:40:54

标签: angularjs security oauth token secret-key

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

除了明显无效的解决方案,例如混淆和代码卷积以及类似的事情,在现代Web应用程序中是否有保护客户机密的最佳实践?我知道这些问题出现在桌面客户端应用程序中,而且我不相信除了“可能会混淆,这会减慢黑客的速度”之外,还有一个解决方案。我们和网络应用程序在一起吗?这个问题没有真正的解决方案吗?

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

2 个答案:

答案 0 :(得分:20)

请注意, OAuth 不是要防止冒充,而是要更多地保护凭据。第三方在不泄露用户凭据的情况下为您验证用户的身份。由于令牌不是凭证,黑客可以做的伤害量和他的行动窗口是有限的。

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


虽然尚未建立保护客户互动的最佳做法,但以下是一些可以最大程度降低风险的方法:

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

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

OAuth 2.0通过为身份验证令牌交换刷新令牌的身份验证令牌,从身份验证中创建一个持续的聊天。你,正在开发人员正在开发一个健谈的应用程序,它做了很多"你的令牌是什么,这是另一个令牌,问我一个令牌,这里是你的新令牌......那你想要什么?" ..." oops,时间到了,刷新令牌在哪里?"

如果这听起来很痛苦,那就有点儿了。 OAuth 2.0旨在让开发人员更轻松地完成此过程。但重要的是,您的令牌的使用寿命越短,黑客就越难以保持欺诈性身份。 的 Refresh Token reference

3)强制执行你的域名:想让嗅探者更少有机会滥用你的盔甲中的缝隙?不要允许跨域请求!

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

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

4)使用第三方API尽可能保持您的访问权限: Google Facebook API和服务已经过单元测试,战斗测试和演变。您越依赖它们来维护用户的身份,您将完成的工作就越少,您的机会就越少。

5)检查IP地址:几乎任何东西都可以伪造,但黑客必须知道IP地址是验证的一部分。这是所有实践中最不确定的,但结合1,2或更多,黑客利用的差距变小,努力的收益逐渐减少。

6)使用"秘密"或第二个参数:您可以为您的用户传递多个令牌。你可以通过自己的Alter-Token。

假装它来回传递ID数据。以非显而易见的方式命名param。将其设为数字​​(例如年龄,身高,地址)。重要的是,你的黑客很少或根本不知道对方要求的是什么!

你可以通过3个参数作为安全措施来投掷一个严重的猴子扳手。

7)请不要提供错误消息,告知他们已被抓获的黑客。给出超时消息而不是"得到你!"如果入侵者没有意识到欺诈被抓住了,他们也不会适应。


我说得不够 - SSL可以省去很多麻烦。

注意:我见过的所有客户端提供商都允许在不暴露Secret的情况下访问其API。 秘密不应该暴露在客户端。

  • 客户端上公开的任何数据都可以闪烁
  • 您使用的任何加密算法都将在客户端公开。

答案 1 :(得分:3)

我来到这里寻找这个问题的答案 - 如何处理SPA中的秘密/身份证。我提出了自己的解决方案,隐藏了服务器中的秘密,但我想确认我在做什么是最好的做法。因此,由于答案可以避免这种情况,我将解释我的流程,希望能帮助那里的任何人。

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

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

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

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

因此,我们的客户输入了他们所有多汁的数据,并且在我们的应用中成为用户时他们会点击提交按钮。

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

  2. 节点服务器通过GET请求接收客户端ID,然后继续向主机(ruby api)发出POST。构建url + grant类型+客户端id +客户端密钥。从而将实现隐藏起来。

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

  4. SPA现在有一个Bearer令牌,我们可以在注册请求的标题中使用。

  5. 从而完成了我们的流程并从世界中隐藏了一个隐藏的秘密。

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

    我选择在Angular方面使用这个lib来为用户提供流量。

    https://github.com/sahat/satellizer

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

    因为这是我自己对如何做这些事情的解释 - 请求反馈。