security - 如何在使用 OAuth2 的资源所有者密码凭据授予类型时保持客户端凭据的 secret 性

标签 security oauth-2.0

我们正在构建一个休息服务,我们希望使用 OAauth 2 进行授权。 current draft (5 月 19 日起的 v2-16)描述 four grant types 。它们是获取授权(访问 token )的机制或流程。

  1. 授权码
  2. 隐式授予
  3. 资源所有者凭据
  4. 客户凭据

看来我们需要支持所有四个,因为它们有不同的目的。前两个(也可能是最后一个)可以从需要访问 API 的第三方应用程序中使用。授权代码是授权 Web 应用程序的标准方法,该应用程序幸运地驻留在安全服务器上,而隐式授权流程将是无法完全保密其凭据的客户端应用程序(例如移动/桌面)的选择应用程序、JavaScript 客户端等)。
我们希望自己使用第三种机制来在移动设备上提供更好的用户体验 - 用户只需直接在应用程序中输入他或她的用户名和密码,而不是将用户带到网络浏览器中的登录对话框等并登录。 我们还希望使用客户端凭据授予类型来获取可用于查看不与任何用户关联的公共(public)数据的访问 token 。在这种情况下,这并不是太多的授权,而是类似于 API key 的东西,我们使用它只向已向我们注册的应用程序授予访问权限,从而使我们可以选择在需要时撤销访问权限。

所以我的问题是:

  1. 您认为我正确理解了不同资助类型的目的吗?
  2. 如何对客户凭据保密?在第三种和第四种情况下,我们都需要将客户端 ID 和客户端 key 保存在客户端的某个位置,这听起来不是一个好主意。
  3. 即使您使用隐式授权类型并且不公开您的客户端 key ,怎样才能阻止其他应用使用相同的授权机制和您的客户端 ID 来冒充您的应用?

总而言之,我们希望能够使用来自客户端应用程序的客户端凭据和资源所有者凭据流。这两个流程都要求您以某种方式存储客户端 key ,但客户端是移动或 JavaScript 应用程序,因此它们很容易被盗。

最佳答案

我面临着类似的问题,而且对 OAuth 也比较陌生。我已经在我们的 API 中实现了“资源所有者密码凭证”,供我们的官方移动应用程序使用 - Web 流程看起来在移动平台上使用起来非常糟糕,一旦用户安装了应用程序并信任这是我们的官方应用程序,他们应该可以放心地直接在应用程序中输入用户名/密码。

问题是,正如您所指出的,我的 API 服务器无法安全地验证应用程序的 client_id。如果我在应用程序代码/包中包含 client_secret,那么它就会暴露给安装该应用程序的任何人,因此要求 client_secret 不会使该过程变得更加安全。所以基本上,任何其他应用程序都可以通过复制 client_id 来冒充我的应用程序。

只是针对您的每一点直接回答:

  1. 我不断重新阅读规范的不同草案,看看是否有任何更改,并且主要关注资源所有者密码凭据部分,但我认为您在这些方面是正确的。客户凭证(4) 我认为也可以由内部或第三方服务使用,这些服务可能需要访问的不仅仅是“公共(public)”信息,例如您可能有分析或需要获取所有用户信息的东西。

  2. 我认为您无法对客户保密。

  3. 没有什么可以阻止其他人使用您的客户端 ID。这也是我的问题。一旦您的代码离开服务器并作为应用程序安装或在浏览器中作为 Javascript 运行,您就不能假设任何内容都是 secret 的。

对于我们的网站,我们在客户凭据流程中遇到了与您所描述的类似的问题。我最终所做的是将身份验证转移到服务器端。用户可以使用我们的 Web 应用程序进行身份验证,但我们 API 的 OAuth token 存储在服务器端,并与用户的 Web session 关联。 Javascript 代码发出的所有 API 请求实际上都是对 Web 服务器的 AJAX 调用。因此,浏览器不会直接使用 API 进行身份验证,而是具有经过身份验证的 Web session 。

您的客户端凭据的用例似乎有所不同,因为您谈论的是第三方应用程序,并且仅通过此方法提供公共(public)数据。我认为您的担忧是有道理的(任何人都可以窃取和使用其他人的 API key ),但如果您只需要免费注册即可获得 API key ,我不明白为什么有人真的想窃取一个。

您可以监控/分析每个 API key 的使用情况,以尝试检测滥用情况,此时您可以使一个 API key 失效并为合法用户提供一个新的 key 。这可能是最好的选择,但它绝不安全。

如果您想将其锁定得更紧,您也可以使用类似刷新 token 的方案,尽管我不知道您真正会获得多少 yield 。如果您每天使 Javascript 公开的 api token 过期一次,并要求第三方使用( secret )刷新 token 进行某种服务器端刷新,那么被盗的 api token 永远不会超过一天。可能会鼓励潜在的代币窃贼直接注册。但对其他人来说有点痛苦,所以不确定这是否值得。

关于security - 如何在使用 OAuth2 的资源所有者密码凭据授予类型时保持客户端凭据的 secret 性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6190381/

相关文章:

html - 除了 <script> 标签之外,我应该删除什么以确保用户输入的 HTML 是安全的?

javascript securty : an AJAX call to record the user's screen resolution, 是否可以防止假号码?

security - DSA:黑客可以用 *just* 公钥做什么?

security - 使用 openid connect 作为多个应用程序的 SSO

amazon-web-services - `aws.cognito.signin.user.admin` 范围在 Amazon Cognito 中是什么意思?

oauth-2.0 - Azure AD JWT token : how to see through which client secret it was granted

java - Java 中 Google OAuth 2 进程中的状态参数

authentication - 如何使用 OAuth2 静默刷新过期的 JWT token ?

Spring Boot 安全性 - 多个身份验证提供程序

php - 如何防止PHP中的SQL注入(inject)?