2010-08-28 133 views
43

我有一个Restful Web服务API,由不同的第三方使用。该API的一部分受到限制(您需要用户名/密码才能访问它)。我想知道什么是实现身份验证的最佳方式?Restful Web服务身份验证

我使用的是https,因此通信是加密的。我有两个想法:

  • 在用户开始使用(受限)服务之前,它使用POST发送用户名/密码(因为正在使用https来加密凭据)。登录成功后,服务器发回与此用户名匹配的随机一次性值(随机数)。当发出下一个请求时,客户端发送先前返回的现时值。服务器匹配用户名和随机数,并沿请求的数据返回新的随机数。每个新请求都使用新的随机数。基本上,这是一个Digest访问认证的轻量级版本。
  • 由于此API是从第三方使用的,因此每个(受限)请求都可以使用用户名/密码。由于正在使用https,它们将被加密。这种方法的崩溃是这样的事实,这不会是Restful兼容(POST会被永远使用)。

我更接近选择第一种方法(它是Restful兼容,相对容易实现,XML,JSON或HTML可以使用而不用改变任何东西),但我想看看你的意见是什么?你有什么建议:第一,第二或第三种方法?

顺便说一句,我在服务器端使用Python。

回答

6

亚马逊网络服务做得很好,请查看一些思路的方法。从本质上讲,他们可以让客户使用他们的密码加密一个特殊的http头。

这里的链接:

我见过的API完成这件事(和方式我目前正在实施的话)

http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html

+0

最好的答复任何措施。如果你可以在这里给出一个很好的算法介绍,我相信你很快就会得到大量的票数!我认为,其中最重要的一点是:“您首先使用您的秘密访问密钥来创建签名密钥,签名密钥的范围是特定区域和服务,另外,签名密钥在创建后七天过期。签名密钥的范围和生命周期是有限的,如果签名密钥受到威胁,数据的风险就会降低。“ – Domi 2015-04-22 16:08:42

23

一种方法是创建一个RESTful资源称为会议它通过创建一个POST它提供了一个用户名和密码。

这里基本上我是如何实现的吧:

POST /sessions { Username: "User", Password: "Password" } 

创建一个有时间限制的会话,并返回一个包含会话密钥值和到期的会话资源。您可能还希望将其作为cookie值返回,以方便实现API客户端。

DELETE /session/{id} 

立即过期会话,因此不能再使用。这用于显式注销。

然后我有用户通过查询参数附加会话密钥,虽然你也可以允许它通过cookie值提交,我建议允许这两个。

我更喜欢的是它非常简单。

很显然,你的场景将决定你的会话应该如何管理,或许它们不受时间限制和无限期限制,也许它们被散列或加密以增加安全性。

如果你在任何地方使用HTTPS,你可能不需要太担心。但是,如果您要使用HTTP,则需要使用类似散列的密钥以及密钥,并说明时间戳以为每个请求生成安全密钥。通过这种方式,您可以通过HTTPS共享密钥,然后切换到HTTP以进一步调用。即使有人设法从请求中嗅出密钥,它几乎可以立即过期并且无用。

声明:我不是安全专家;-)。

+1

如果您在服务器上使用会话,那么您的API不是RESTful,因为服务器有一个状态。每个请求应包含所有必要的数据,服务器不应依赖会话。将会话数据保存在客户端在每个请求的标头中发送的JSON Web令牌中。你可以在那里打包一个序列化的用户对象(这就是我如何做到这一点)。 – felixfbecker 2015-06-22 08:43:31

+0

这似乎有些迂腐,并且还认为认证严格的“RESTful”很重要。像JWT这样的方法确实可以解决这个问题,只要它对您的应用程序来说是必要的或重要的就可以这样做。 – 2015-06-24 18:25:38

4

假设服务在浏览器从不消耗,通信被反正加密,我认为没有害处在第二方法的变形例:添加X-集管与每个请求发送用户名/密码,例如:

GET /foo HTTP/1.1 
Host: www.bar.com 
X-MyUsername: foo 
X-MyPassword: bar 

另一个想法是使用HTTP基本身份验证,并发送一个Authorization: Basic base64(user:password)-标题。也就是说,如果连接始终是加密的。

+0

在这种情况下,你如何实现'登录'和'注销'? – 2013-07-25 09:48:09

+2

我认为在这种情况下没有“登录”和“注销”,因为您在每个请求中都发送用户名/密码。 – 2013-10-01 20:11:36

+0

由于跨站请求伪造,基本身份验证仍然不够好。 – 2014-06-16 18:07:11

8

没有理由不在这里使用HTTP身份验证。

也就是说,发布POST时间块随机数的概念可以很好地工作。但是,这就是为什么你需要跳过这个额外的箍环的动机。

由于验证用户的实际花费(如果您不知道,可以调整bcrypt以显着实时执行散列函数),因此在对原始密码使用bcrypt散列时会考虑此技术。 。做出这样的选择是为了使服务“登录”一次使用密码,该密码将通过bcrypt经历昂贵的验证过程,并且然后将获得时间阻塞的令牌以换取将绕过bcrypt过程的未来请求。

在bcrypt进程的情况下,使用HTTP认证,该服务可以使用正常密码以及令牌。这样用户可以随时使用密码进行他们的服务,但这只会变得昂贵。所以他们可以做到这一点,他们只是不应该。该服务不关心客户端使用哪种认证技术。

随机提供nonce服务以提高吞吐量。

除此之外,它是标准的HTTP身份验证,但是采用了新的方案。

+1

不使用HTTP身份验证的一个原因是,浏览器会随每个请求自动发送该消息,从而使您受到CSRF攻击。不过,使用自定义授权方案是可以的。或者使用自定义标题。 – 2014-06-16 18:06:42