我有一个Restful Web服务API,由不同的第三方使用.该API的一部分受到限制(您需要用户名/密码才能访问它).我想知道实现身份验证的最佳方法是什么?
我正在使用https,因此通信是加密的.我有两个想法:
在用户开始使用(受限制)服务之前,它使用POST发送用户名/密码(因为https正在使用凭据加密).登录成功后,服务器会发回与此用户名匹配的随机一次性使用值(nonce).当发出下一个请求时,除了用户名,客户端发送先前返回的现时.服务器匹配username和nonce,并沿着请求的数据返回新的nonce.每个新请求都使用新的nonce.基本上,这是Digest访问身份验证的轻量级版本.
由于此API是从第三方使用的,因此用户名/密码可用于每个(受限制的)请求.由于正在使用https,因此它们将被加密.这种方法的缺点是这不符合Restful(POST将始终使用).
我更接近于选择第一种方法(它是宁静的标准,比较容易实现,XML,JSON或HTML,可以在不改变任何使用),但我想看看你有什么看法?你推荐什么:第一种,第二种或第三种方法?
顺便说一下,我在服务器端使用Python.
我在API(以及当前实现它的方式)中看到这种方法的一种方法是创建一个名为Session的RESTful资源,它通过提供用户名和密码的POST创建.
基本上我是如何实现它的:
POST /sessions { Username: "User", Password: "Password" }
创建一个时间限制会话并返回包含会话密钥值和到期的会话资源.您可能还希望将此值作为cookie值返回,以便于实现API客户端.
DELETE /session/{id}
立即使会话到期,因此无法再使用它.这用于显式注销.
然后我让用户通过查询参数附加会话密钥,虽然你也可以允许它通过cookie值提交,我建议允许两者.
我更喜欢这个,它非常简单.
显然,您的方案将在某种程度上决定您的会话应该如何管理,也许它们不受时间限制并且无限期地持续,并且可能为了增加安全性而对它们进行散列或加密.
如果您在任何地方使用HTTPS,您可能不需要太担心.但是,如果要使用HTTP,则需要使用哈希和密钥之类的东西,并说出时间戳以按请求生成安全密钥.这样,您可以通过HTTPS共享密钥,然后切换到HTTP以进一步调用.即使有人设法从请求中嗅出密钥,它也几乎可以立即过期并且无用.
免责声明:我不是安全专家;-).
没有理由不在这里使用HTTP身份验证.
也就是说,POST获取时间块nonce的概念可以很好地工作.但这就是为什么你需要首先跳过这个额外的箍的动机.
当使用bcrypt哈希作为原始密码时,考虑了这种技术,因为验证用户的实际费用(如果你不知道,可以调整bcrypt以便花费大量实时来执行哈希函数).选择是使用密码通过bcrypt通过昂贵的验证过程提供服务"登录"的选项,然后获得时间阻止令牌以换取将绕过bcrypt进程的未来请求.
对于bcrypt进程,使用HTTP身份验证,该服务既可以使用普通密码,也可以使用令牌.这样,用户可以随时使用密码进行服务,但这只会变得昂贵.所以他们可以做到这一点,他们只是不应该这样做.该服务不关心客户端使用哪种身份验证技术.
nonce服务作为一个提供,以提高吞吐量.
除此之外,它是标准的HTTP身份验证,但采用了新的方案.
亚马逊网络服务做得很好,查看一些想法的方法.基本上,他们让客户端使用他们的密码加密特殊的http头.
这是链接:
http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html