繁体   English   中英

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

[英]How to keep the client credentials confidential, while using OAuth2's Resource Owner Password Credentials grant type

我们正在构建 rest 服务,我们希望使用 OAauth 2 进行授权。 当前的草案(5 月 19 日的 v2-16)描述了四种资助类型 它们是获取授权(访问令牌)的机制或流程。

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

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

所以我的问题是:

  1. 您认为我正确理解了不同资助类型的目的吗?
  2. 您如何对客户凭证保密? 在第三种和第四种情况下,我们都需要在客户端的某个地方拥有客户端 ID 和客户端密码,这听起来不是一个好主意。
  3. 即使您使用隐式授权类型并且不公开您的客户端密码,有什么可以阻止另一个应用程序使用相同的授权机制和您的客户端 ID 来模拟您的应用程序?

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

我面临着类似的问题,而且对 OAuth 也比较陌生。 我已经在我们的 API 中实现了“资源所有者密码凭据”,供我们的官方移动应用程序使用——web 流看起来就像它们在移动平台上使用起来太可怕了,一旦用户安装了应用程序并信任这是我们的官方应用程序,他们应该觉得直接在应用程序中输入用户名/密码很舒服。

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

只是为了直接回答你的每一点:

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

  2. 我认为你不能对客户保密。

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

对于我们的网站,我们遇到了与您描述的客户凭证流程类似的问题。 我最终做的是将身份验证移至服务器端。 The user can authenticate using our web app, but the OAuth token to our API is stored on the server side, and associated with the user's web session. 所有 API 请求 Javascript 代码实际上都是对 Z2567A5EC9705EB7AC2C984033E06 服务器的 AJAX 调用。 所以浏览器没有直接使用 API 进行身份验证,而是有一个经过身份验证的 web session。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM