5

我可能需要为我正在创建的 API 实现 OAuth2.0 服务器。此 API 将允许第 3 方代表用户执行操作。

OAuth2.0 有 3 个电源调用。首先,有一个电话提示用户同意。这会返回一个code. 第二个是用code交换 的地方access token。最后,access token用于代表用户调用 API。

为了实现,我认为第一次调用会生成一个随机字符串,它充当code. 然后code将带有指向当前用户的指针和随机的 存储在数据库中HMAC Key,然后将随机数据作为 返回给第 3 方code

当第 3 方请求 时access token,会生成另一条随机数据并与code. 此字符串使用HMAC key来自步骤 1 的 签名,然后此签名字符串和签名与签名一起返回以形成access token.

当 API 调用发生时,从数据库中检索与hmac key提供的对应的。access_token的签名access_token使用 hmac 密钥进行验证。

用户只需从其授权 HMAC 密钥列表中删除一个 HMAC 密钥,即可撤销第 3 方访问。此外,但只是签署随机数据,我可以避免存储每个创建的每个 access_token,而是维护一个简短的 hmac 密钥列表。

无论如何,这是我第一次尝试思考这个问题。令人惊讶的是,关于有效实现 OAuth2.0 的服务器端的信息很少。我宁愿在数据库中保留尽可能少的信息。签署随机数据然后撤销 HMAC 密钥的优点是我不必存储每个access token授权调用生成的每个数据。

需要思考!一定有更好的方法!

编辑:

我不是在寻找实现。不过还是谢谢!另外,我假设整个系统将通过 HTTPs 运行。另外,我说的是纯 OAuth2.0 流程,我不是在谈论带有签名和客户端密钥的 OAuth1.0。我在问如何设计 OAuth2.0 服务器背后的密码学,该服务器将以与(例如)Google 的 OAuth2.0 流程类似的方式工作。

4

3 回答 3

9

我对此没有确切的答案,但让我们尝试将这些部分组合在一起 -

i) 我不太确定您是否需要将授权码长期保存在数据库中。这就是 Facebook 所说的——

OAuth 授权代码的新安全限制 我们只允许将授权代码交换为访问令牌一次,并要求在创建后 10 分钟内将它们交换为访问令牌。这符合 OAuth 2.0 规范,该规范从一开始就声明“授权码必须是短暂的且一次性使用”。有关更多信息,请查看我们的身份验证文档。

请参阅此链接,https://developers.facebook.com/roadmap/completed-changes/(12 月 5 日,更改)。

ii)在第 1 步之前做什么,将授权码和 HMAC 密钥保存在数据库中。让我们有 10 分钟的授权码(或任何你认为有必要的),然后删除授权码。

iii) 假设您有一个单点登录服务来验证客户端的凭据。当客户端应用程序访问令牌交换端点(访问令牌的身份验证代码)时,您需要获取 HMAC 密钥并返回访问令牌。为什么不添加(一些随机数据+时间戳+客户ID/客户名称(或可用于唯一标识用户的东西))并使用密钥对其进行签名并将所有这些数据作为访问令牌返回。
您可以考虑使用新的 HMAC 密钥并替换旧的。

iv) 当客户端使用令牌命中任何 API 端点时,让服务内部调用CustomerIDExtractorService 从数据库中获取 HMAC 密钥并解密访问令牌并将 customerID 返回给相关 API。然后,独立进程可以使用客户 ID 来获取数据。所以基本上,我要求您将登录/令牌生成/令牌信息提​​取过程分离到一个单独的单元中。

让我们尝试将其映射到 Google 如何执行此类操作
i)您使用应用程序并登录 Google Oauth。(让谷歌的黑匣子 X 处理登录)。
ii) 您的应用程序访问令牌交换端点 -> 服务在内部检查代码是否有效。如果是,服务会结合一些数据 + customerID 并对其进行签名并将其作为访问令牌返回给应用程序。
iii) 应用程序现在点击(比如说)google+ 端点。在内部,该服务将令牌传输到黑匣子 X,后者解密令牌并将客户 ID 返回给 G+ 服务。g+ 然后将 C_ID 映射到相关的客户数据。

另一个建议

根据应用程序请求的范围,您可以向访问令牌添加更多信息。可能会根据应用程序选择的范围创建一个 JSON 对象并添加/删除字段。将 JSON 字符串签名为访问令牌。

于 2013-05-01T10:52:41.790 回答
0

实际上,大多数实现都是在 OAuth 2.0 中通过 https 而不是 mac 使用不记名令牌,请查看此演示文稿第 54-56 页,了解为什么更喜欢不记名,另一方面,spring 实现不支持 OAuth 2.0 的 MAC 令牌,并且存在一个未解决的问题,但是它仍然开放

暂时如果你正在寻找spring implementation demo你可以查看这个source code但是它使用数据库来存储令牌,并且资源服务器和授权服务器之间必须完成连接,在这个demo中使用数据库.

Spring OAuth 2.0 的开源实现之一是cloudfoundry 的 UAA,我参加了一个关于它的会议,他们也告诉他们必须在两台服务器之间进行通信。关联

于 2013-04-29T16:15:40.617 回答
0

似乎你的描述开始不错,但我必须承认我只能部分遵循你的方法。AFAIK OAuth2 严重依赖 HTTPS 而不是签名请求,尽管我猜你可以自由使用。

我不确定您提出的撤消访问权限的概念。通常这将仅依赖于访问令牌(它应该在某个时间点到期,您可以撤销它,并且可以更新它)。如果对于 API 请求,您正在提取用户 ID 的密钥,那么您的代码可能与“用户”概念而不是 OAuth 客户端(具有角色、范围、资源)紧密相关

无论如何,这不是一个简单的标准,我想讨论可能会持续很长时间,即使那样我也不确定是否可以涵盖所有内容。我相信您已经在以下位置查看了 RFC:

https://www.rfc-editor.org/rfc/rfc6749

我还从您的个人资料中看到您可能是一名 Java 开发人员。在这种情况下,查看 Spring-security-oauth2 可能是个好主意:

https://github.com/SpringSource/spring-security-oauth

如果您的解决方案不使用 Java,那么您在问题中提到的很多问题都已被此类项目处理并解决,因此它应该会给您很多想法。如果您将使用 Java,那么它可能会对您有很大帮助。

希望能帮助到你!

于 2013-04-27T21:42:43.043 回答