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