高效的OAuth2.0服务器/提供商如何运作?

时间:2013-04-24 19:25:40

标签: security encryption cryptography oauth-2.0 digital-signature

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

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

为了实现,我认为第一个调用生成一个随机字符串,作为code。然后将code存储在数据库中,其中包含指向当前用户的指针和随机HMAC Key,然后随机数据将作为code返回给第三方。

当第三方请求access token时,生成另一条随机数据并与code连接。此字符串使用步骤1中的HMAC key进行签名,然后返回此签名字符串和签名以及签名以形成access token

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

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

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

需要思考!必须有更好的方法!

编辑:

我不是在寻找实施方案。谢谢你!此外,我假设整个系统将运行HTTPs。另外,我说的是纯OAuth2.0流程,我用签名和客户端密钥来讨论OAuth1.0。我问的是如何在OAuth2.0服务器后面设计密码术,该服务器的工作方式与(例如)Google的OAuth2.0流程类似。

3 个答案:

答案 0 :(得分:9)

我对此没有确切的答案,但让我们试着把各个部分放在一起 -

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

  

OAuth授权码的新安全限制   我们只允许一次授权代码交换访问令牌,并要求他们交换访问权限   令牌在他们创作的10分钟内。这符合   OAuth 2.0 Spec从一开始就说“授权   代码必须是短期和单次使用“。有关更多信息,请检查   我们的身份验证文档。

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

ii)如果要执行您在第1步之前所做的操作,请将授权码和HMAC密钥保存在数据库中。 让我们拥有10分钟的授权码(或您认为必要的任何内容),然后删除授权码。

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

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

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

另一个建议

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

答案 1 :(得分:0)

好像你的描述开始了,但是我必须承认我只能部分地遵循你的方法。 AFAIK OAuth2在很大程度上依赖于HTTPS而不是签名请求,尽管我猜你可以自由使用它。

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

在任何情况下,它都不是一个简单的标准,我想这个讨论可能会持续很长时间,即便如此,我也不确定是否可以涵盖所有内容。我相信您已经在以下位置审核了RFC:

http://tools.ietf.org/html/rfc6749

我也从您的个人资料中看到您可能是Java开发人员。在这种情况下,最好在以下位置查看Spring-security-oauth2:

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

如果您的解决方案不会使用Java,那么您在问题中提到的很多问题都会被这样的项目所接近并解决,所以它应该给您很多想法。如果您将使用Java,那么它可能会对您有所帮助。

希望它有所帮助!

答案 2 :(得分:0)

实际上大多数实现都是在OAuth 2.0中使用https而不是mac的承载令牌,请检查this presentation pages 54-56为什么更喜欢承载,另一方面Spring实现不支持OAuth 2.0的MAC令牌,并且存在一个未解决的问题它只是it is still open

暂时如果您正在寻找Spring实现演示,您可以查看source code但是它使用数据库来存储令牌,并且必须在资源服务器和授权服务器之间建立连接,在此演示中使用数据库。

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