我可能需要为我正在创建的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流程类似。
答案 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