RESTful身份验证意味着什么?它是如何工作的?我在谷歌上找不到好的概览。我唯一的理解是在URL中传递会话密钥(记住),但这可能是错误的。


当前回答

这当然不是关于“会话密钥”,因为它通常用于指在REST的所有约束条件下执行的无会话身份验证。每个请求都是自我描述的,携带足够的信息,可以在没有任何服务器端应用程序状态的情况下自行授权请求。

最简单的方法是从RFC 2617中的HTTP内置认证机制开始。

其他回答

我怀疑那些热情高喊“HTTP认证”的人是否曾尝试过用REST制作基于浏览器的应用程序(而不是机器对机器的web服务)(无意冒犯-我只是认为他们从未面临过复杂的问题)。

我在RESTful服务上使用HTTP身份验证时发现的问题是:

用户通常会收到一个难看的浏览器制作的登录框,这对用户非常不友好。您不能添加密码检索、帮助框等。注销或以其他名称登录是一个问题-浏览器将一直向站点发送身份验证信息,直到您关闭窗口超时很困难

这里有一篇非常有见地的文章,逐点解决了这些问题,但这导致了许多特定于浏览器的javascript黑客、变通方法等。因此,它也不向前兼容,因此在发布新浏览器时需要不断维护。我不认为这是一个干净清晰的设计,而且我觉得这是一项额外的工作,很头疼,因为这样我才能热情地向朋友展示我的REST徽章。

我认为饼干是解决方案。但是等等,饼干是邪恶的,不是吗?不,他们不是,饼干经常被使用的方式是邪恶的。cookie本身只是一条客户端信息,就像您浏览时浏览器会跟踪的HTTP身份验证信息一样。这段客户端信息在每次请求时都会被发送到服务器,就像HTTP身份验证信息一样。从概念上讲,唯一的区别是,这段客户端状态的内容可以由服务器作为其响应的一部分来确定。

通过使用以下规则使会话成为RESTful资源:

会话将密钥映射到用户id(可能还有超时的最后一个操作时间戳)如果会话存在,则意味着密钥有效。登录意味着发布到/会话,新密钥设置为cookie注销意味着删除/会话/{key}(要记住,我们是一个浏览器,HTML5还有很长的路要走)通过在每次请求时将密钥作为cookie发送并检查会话是否存在和有效来完成身份验证

现在,与HTTP身份验证的唯一区别是,身份验证密钥由服务器生成,并发送给客户端,客户端继续发送该密钥,而不是客户端根据输入的凭据计算该密钥。

converter42补充道,当使用https(我们应该这样做)时,cookie必须设置其安全标志,这样身份验证信息就不会通过非安全连接发送。说得好,我自己都没看到。

我觉得这是一个足够好的解决方案,但我必须承认,我还不够安全专家来识别这个方案中的潜在漏洞-我所知道的是,数百个非RESTful web应用程序使用基本相同的登录协议(PHP中的$_SESSION,Java EE中的HttpSession等),就像接受语言可以用于访问翻译资源等。我觉得这是一样的,但也许其他人不是这样?你们觉得呢,伙计们?

首先也是最重要的,RESTful web服务是无状态的(或者换句话说,无会话的)。因此,RESTful服务没有也不应该包含会话或cookie的概念。在RESTful服务中进行身份验证或授权的方法是使用RFC 2616 HTTP规范中定义的HTTP授权头。每个请求都应该包含HTTP授权头,并且请求应该通过HTTPs(SSL)连接发送。这是在HTTPRESTful web服务中进行身份验证和验证请求授权的正确方法。我已经为Cisco Systems的Cisco PRIME Performance Manager应用程序实现了RESTful web服务。作为web服务的一部分,我还实现了身份验证/授权。

2019年2月16日更新

下面前面提到的方法本质上是OAuth2.0的“资源所有者密码凭据”授予类型。这是一种简单的起床和跑步方式。然而,使用这种方法,组织中的每个应用程序最终都将拥有自己的身份验证和授权机制。建议采用“授权代码”授权类型。此外,在下面我先前的回答中,我建议使用浏览器localStorage来存储身份验证令牌。然而,我开始相信饼干是实现这一目的的正确选择。在StackOverflow的回答中,我详细介绍了我的原因、授权代码授予类型实现方法、安全考虑等。


我认为以下方法可用于REST服务身份验证:

创建一个登录RESTful API以接受用户名和密码进行身份验证。使用HTTP POST方法在传输过程中防止缓存和SSL安全成功认证后,API返回两个JWT-一个访问令牌(有效期更短,例如30分钟)和一个刷新令牌(有效性更长,例如24小时)客户端(一个基于web的UI)将JWT存储在本地存储中,并且在随后的每个API调用中都会传递“Authorization:Bearer#access token”标头中的访问令牌API通过验证签名和到期日期来检查令牌的有效性。如果令牌有效,请检查用户(它将JWT中的“sub”声明解释为用户名)是否可以通过缓存查找访问API。如果用户被授权访问API,则执行业务逻辑如果令牌过期,API将返回HTTP响应代码400客户端在收到400/401时,调用另一个REST API,并在“Authorization:Bearer#refresh token”标头中使用刷新令牌来获取新的访问令牌。收到带有刷新令牌的呼叫时,通过检查签名和到期日期来检查刷新令牌是否有效。如果刷新令牌有效,则从DB刷新用户的访问权限缓存,并返回新的访问令牌和刷新令牌。如果刷新令牌无效,则返回HTTP响应代码400如果返回了新的访问令牌和刷新令牌,请转到步骤2。如果返回HTTP响应代码400,则客户端假定刷新令牌已过期,并向用户请求用户名和密码要注销,请清除本地存储

使用这种方法,我们每30分钟就要执行一次昂贵的操作,即加载具有用户特定访问权限详细信息的缓存。因此,如果取消了访问或授予了新的访问权限,则需要30分钟才能反映或注销,然后登录。

这里是一个真正且完全的RESTful身份验证解决方案:

在身份验证服务器上创建公钥/私钥对。将公钥分发给所有服务器。当客户端进行身份验证时:3.1.发行包含以下内容的代币:到期时间用户名(可选)用户IP(可选)密码散列(可选)3.2.使用私钥加密令牌。3.3.将加密令牌发送回用户。当用户访问任何API时,还必须传递其身份验证令牌。服务器可以通过使用身份验证服务器的公钥解密令牌来验证令牌是否有效。

这是无状态/RESTful身份验证。

注意,如果包含密码哈希,则用户还将发送未加密的密码以及身份验证令牌。服务器可以通过比较散列来验证密码是否与用于创建身份验证令牌的密码匹配。需要使用HTTPS之类的安全连接。客户端的Javascript可以处理获取用户的密码并将其存储在客户端,可以存储在内存中,也可以存储在cookie中,可能使用服务器的公钥进行加密。

我认为restful身份验证涉及将身份验证令牌作为请求中的参数传递。示例是api对apikey的使用。我认为使用cookie或http身份验证不合格。