RESTful身份验证

rest authentication restful-authentication rest-security

359240 观看

14回复

4143 作者的声誉

RESTful身份验证的含义是什么?它是如何工作的?我无法在Google上找到一个很好的概述。我唯一的理解是你在URL中传递会话密钥(remeberal),但这可能是非常错误的。

作者: Jim Keener 的来源 发布者: 2008 年 11 月 26 日

回应 (14)


22

1726 作者的声誉

它肯定不是关于“会话密钥”,因为它通常用于指代在REST的所有约束内执行的无会话身份验证。每个请求都是自我描述的,携带足够的信息来自行授权请求,而不需要任何服务器端应用程序状态。

解决此问题的最简单方法是从RFC 2617中的 HTTP内置身份验证机制开始。

作者: Justin Sheehy 发布者: 26.11.2008 03:06

1

0 作者的声誉

从我的理解中回答这个问题......

使用REST的身份验证系统,您无需实际跟踪或管理系统中的用户。这是通过使用HTTP方法POST,GET,PUT,DELETE来完成的。我们采用这4种方法,并将它们视为数据库交互,如CREATE,READ,UPDATE,DELETE(但在Web上我们使用POST和GET,因为这是锚标记当前支持的)。因此将POST和GET视为我们的CREATE / READ / UPDATE / DELETE(CRUD),然后我们可以在我们的Web应用程序中设计路径,以便推断出我们正在实现的CRUD操作。

例如,在Ruby on Rails应用程序中,我们可以构建我们的Web应用程序,这样如果登录的用户访问http://store.com/account/logout,那么该页面的GET可以被视为用户尝试注销。在我们的rails控制器中,我们将构建一个操作,将用户注销并将其发送回主页。

登录页面上的GET将生成一个表单。登录页面上的POST将被视为登录尝试并获取POST数据并使用它进行登录。

对我来说,这是一种使用映射到其数据库含义的HTTP方法的做法,然后构建一个认证系统,考虑到这一点,您不需要传递任何会话ID或跟踪会话。

我还在学习 - 如果你发现任何我说错了,请纠正我,如果你了解更多,请将它发回这里。谢谢。

作者: mike 发布者: 19.01.2009 06:14

12

35271 作者的声誉

我认为restful身份验证涉及将身份验证令牌作为参数传递给请求。例如api使用apikeys。我不相信使用cookies或http auth符合条件。

作者: Bjorn Tipling 发布者: 19.01.2009 06:45

406

8056 作者的声誉

我怀疑那些热心地喊“HTTP身份验证”的人是否尝试过用REST创建一个基于浏览器的应用程序(而不是机器到机器的Web服务)(没有冒犯的意图 - 我只是觉得他们没有遇到过复杂的问题) 。

我在RESTful服务上使用HTTP身份验证时发现的问题是生成可在浏览器中查看的HTML页面:

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

铲球这些逐点非常有见地的文章是在这里,但是这导致了很多特定浏览器的JavaScript两轮牛车,变通办法变通办法,等等的。因此,它也不是向前兼容的,因此在发布新浏览器时需要不断维护。我不认为干净清晰的设计,而且我觉得这是一项额外的工作和头痛,所以我可以热情地向我的朋友展示我的REST徽章。

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

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

  • 一个会话映射一个关键用户ID(也可能是最后行动时间戳超时)
  • 如果存在会话,则表示该密钥有效。
  • 登录意味着POST到/ sessions,新密钥被设置为cookie
  • 注销意味着删除/ sessions / {key}(使用重载的POST,记住,我们是浏览器,HTML 5还有很长的路要走)
  • 通过在每个请求时将密钥作为cookie发送并检查会话是否存在且有效来完成身份验证

现在,与HTTP身份验证的唯一区别在于,身份验证密钥由服务器生成并发送给不断发送回来的客户端,而不是客户端从输入的凭据计算它。

converter42补充说,当使用https(我们应该)时,重要的是cookie将设置其安全标志,以便永远不会通过非安全连接发送身份验证信息。好极了,自己没见过。

我认为这是一个运行良好的充分解决方案,但我必须承认,我不足以识别此方案中的潜在漏洞 - 我所知道的是,数百个非RESTful Web应用程序使用的基本相同登录协议(PHP中的$ _SESSION,Java EE中的HttpSession等)。cookie头内容仅用于寻址服务器端资源,就像接受语言可能用于访问翻译资源一样,等等。我觉得它是一样的,但也许其他人不一样?你们觉得怎么样?

作者: skrebbel 发布者: 16.07.2009 07:39

535

36632 作者的声誉

决定

如何在RESTful客户端 - 服务器架构中处理身份验证是一个有争议的问题。

通常,可以通过以下方式在SOA over HTTP世界中实现:

  • 通过HTTPS进行HTTP基本身份验证;
  • Cookie和会话管理;
  • HTTP标头中的令牌(例如OAuth 2.0 + JWT);
  • 使用其他签名参数查询身份验证

您必须调整甚至更好地混合这些技术,以最好地匹配您的软件架构。

每种身份验证方案都有自己的PRO和CON,具体取决于安全策略和软件体系结构的用途。

通过HTTPS进行HTTP基本身份验证

大多数Web服务都使用基于标准HTTPS协议的第一个解决方案。

GET /spec.html HTTP/1.1
Host: www.example.org
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

它很容易实现,默认情况下在所有浏览器上都可用,但是有一些已知的缺点,比如浏览器上显示的糟糕的身份验证窗口,它会持续存在(这里没有类似LogOut的功能),一些服务器端额外的CPU消耗,以及将用户名和密码(通过HTTPS)传输到服务器的事实(在键盘输入期间让密码仅保留在客户端,并在服务器上存储为安全散列应该更安全) 。

我们可能会使用摘要式身份验证,但它也需要HTTPS,因为它容易受到MiMReplay攻击,并且特定于HTTP。

通过Cookies会话

说实话,在服务器上管理的会话并非真正无状态。

一种可能性是维护cookie内容中的所有数据。并且,根据设计,cookie在服务器端处理(客户端,实际上甚至不会尝试解释此cookie数据:它只是在每次连续请求时将其交还给服务器)。但是这个cookie数据是应用程序状态数据,因此客户端应该在纯无状态世界中管理它,而不是服务器。

GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: theme=light; sessionToken=abc123

cookie技术本身是HTTP链接的,所以它不是真正的RESTful,它应该是独立于协议的,恕我直言。它易受MiMReplay攻击。

通过令牌(OAuth2)授予

另一种方法是在HTTP标头中放置一个令牌,以便对请求进行身份验证。例如,这就是OAuth 2.0的功能。请参阅RFC 6749

 GET /resource/1 HTTP/1.1
 Host: example.com
 Authorization: Bearer mF_9.B5f-4.1JqM

简而言之,这与cookie非常相似,并且遇到同样的问题:不是无状态,依赖于HTTP传输细节,并且受到很多安全漏洞的影响 - 包括MiM和Replay - 所以只能通过HTTPS使用。通常,JWT用作令牌。

查询验证

查询身份验证包括通过URI上的一些其他参数对每个RESTful请求进行签名。请参阅此参考文章

它在本文中定义如下:

必须通过使用私有凭证作为签名令牌对以小写字母顺序排序的查询参数进行签名来验证所有REST查询。应在URL编码查询字符串之前进行签名。

这种技术可能与无状态架构更兼容,也可以通过轻型会话管理(使用内存中会话而不是数据库持久性)来实现。

例如,以下是上面链接中的通用URI示例:

GET /object?apiKey=Qwerty2010

应该这样传播:

GET /object?timestamp=1261496500&apiKey=Qwerty2010&signature=abcdef0123456789

正在签名的字符串是/object?apikey=Qwerty2010&timestamp=1261496500,并且签名是使用API​​密钥的私有组件的该字符串的SHA256哈希。

服务器端数据缓存始终可用。例如,在我们的框架中,我们在SQL级别而不是在URI级别缓存响应。因此,添加此额外参数不会破坏缓存机制。

有关基于JSON和REST的客户端 - 服务器ORM / SOA / MVC框架中的RESTful身份验证的一些详细信息,请参阅此文章。由于我们不仅允许通过HTTP / 1.1进行通信,还允许通过命名管道或GDI消息(本地)进行通信,因此我们尝试实现真正的RESTful身份验证模式,而不依赖于HTTP特性(如头或cookie)。

稍后注意:在URI中添加签名可能被视为不良做法(因为例如它将出现在http服务器日志中),因此必须减轻它,例如通过适当的TTL来避免重放。但是,如果您的http日志遭到破坏,您肯定会遇到更大的安全问题。

在实践中,即将到来的OAuth 2.0的MAC令牌认证可能是关于“由令牌授予”当前方案的巨大改进。但这仍然是一项正在进行的工作,并且与HTTP传输有关。

结论

值得推断的是,REST不仅基于HTTP,即使在实践中,它也主要通过HTTP实现。REST可以使用其他通信层。因此,无论谷歌如何回答,RESTful身份验证都不仅仅是HTTP身份验证的同义词。它根本不应该使用HTTP机制,但应从通信层中抽象出来。如果您使用HTTP通信,由于Let的加密计划,没有理由不使用正确的HTTPS,这是任何身份验证方案所必需的。

作者: Arnaud Bouchez 发布者: 23.08.2011 09:29

7

71 作者的声誉

这是做到这一点的方法:使用OAuth 2.0进行登录

只要支持OAuth,您就可以使用Google以外的其他身份验证方法。

作者: moshe beeri 发布者: 08.12.2011 10:44

15

451 作者的声誉

@skrebel(http://www.berenddeboer.net/rest/authentication.html)提到的“非常富有洞察力”的文章讨论了一种令人费解但却非常破碎的身份验证方法。

您可以尝试访问该页面(应该只对经过身份验证的用户可查看)http://www.berenddeboer.net/rest/site/authenticated.html,无需任何登录凭据。

(对不起,我无法对答案发表评论。)

我会说REST和身份验证根本不混合。REST意味着无状态,但“经过身份验证”是一种状态。你不能将它们放在同一层。如果你是一个RESTful的拥护者并对国家不满,那么你必须使用HTTPS(即将安全问题留给另一层)。

作者: Ji Han 发布者: 15.10.2012 07:35

32

362 作者的声誉

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

鲁本斯戈麦斯。

作者: user2213684 发布者: 26.03.2013 11:13

35

2602 作者的声誉

说实话,我在这里看到了很好的答案,但是让我感到困扰的是当有人将整个无状态概念推向一个极端的教条时。它让我想起那些只想拥抱纯粹OO的老Smalltalk粉丝,如果某些东西不是一个对象,那么你做错了。给我一个休息时间。

RESTful方法应该让您的生活更轻松,减少会话的开销和成本,尝试遵循它,因为这是明智的做法,但是你遵循一个学科(任何学科/指南)到极端的那一刻不再提供预期的好处,那么你做错了。今天一些最好的语言同时具有函数式编程和面向对象。

如果您解决问题的最简单方法是将身份验证密钥存储在cookie中并在HTTP标头上发送,那么请执行此操作,只是不要滥用它。请记住,如果会话变得沉重而且很大,如果所有会话都包含一个包含密钥的短字符串,那么会话有什么大不了?

我愿意在评论中接受更正,但我只是没有看到(到目前为止)让我们的生活变得悲惨的一点,只是避免在我们的服务器中保留一个大的哈希词典。

作者: arg20 发布者: 13.08.2013 08:09

48

3728 作者的声誉

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

  1. 在身份验证服务器上创建公钥/私钥对。
  2. 将公钥分发给所有服务器。
  3. 当客户端进行身份验证时:

    3.1。发出包含以下内容的令牌:

    • 到期时间
    • 用户名(可选)
    • 用户IP(可选)
    • 密码哈希(可选)

    3.2。使用私钥加密令牌。

    3.3。将加密的令牌发送回用户。

  4. 当用户访问任何API时,他们还必须传递其身份验证令牌。

  5. 服务器可以通过使用auth服务器的公钥解密来验证令牌是否有效。

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

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

作者: jcoffland 发布者: 14.10.2013 09:29

1

19 作者的声誉

使用公钥基础设施,其中密钥的注册涉及适当的绑定,确保公钥以确保不可否认性的方式绑定到分配给它的个人

http://en.wikipedia.org/wiki/Public_key_infrastructure。如果您遵循正确的PKI标准,则可以识别并锁定不正当使用被盗密钥的人或代理。如果代理需要使用证书,则绑定会非常紧密。一个聪明而快速移动的小偷可以逃脱,但他们会留下更多的面包屑。

作者: DonB. 发布者: 02.11.2013 04:08

130

3077 作者的声誉

这里的好人已经对这个主题说了足够的话。但这是我的2美分。

有两种互动模式:

  1. 人机对话(HTM)
  2. 机器对机器(MTM)

机器是公共分母,表示为REST API,演员/客户端是人或机器。

现在,在一个真正的RESTful架构中,无状态的概念意味着必须为每个请求提供所有相关的应用程序状态(意味着客户端状态)。相关的是,REST API需要处理请求并提供适当的响应。

当我们在人机对应用环境中考虑这一点时,Skrebbel在上面指出“基于浏览器”,这意味着在浏览器中运行的(web)应用程序需要在每个请求中发送其状态和相关信息它使后端REST API。

考虑一下:您有一个REST API的数据/信息平台公开资产。也许您有一个处理所有数据立方体的自助BI平台。但是您希望您的(人类)客户通过(1)Web应用程序,(2)移动应用程序和(3)某些第三方应用程序访问此用户。最后,即便是MTM链也会导致HTM - 正确。因此,人类用户仍然处于信息链的顶端。

在前两种情况下,您有一个人机交互的案例,即人类用户实际消费的信息。在最后一种情况下,您有一个使用REST API的机器程序。

身份验证的概念适用于所有人。您将如何设计此类以便以统一,安全的方式访问REST API?我看到这个的方式,有两种方式:

方式1:

  1. 首先没有登录。每个请求都执行登录
  2. 客户端向每个请求发送其标识参数+请求特定参数
  3. REST API接受它们,转身,ping用户存储(无论是什么)并确认auth
  4. 如果auth建立,请为请求提供服务; 否则,使用适当的HTTP状态代码拒绝
  5. 对目录中所有REST API的每个请求重复上述操作

方法2:

  1. 客户端以auth请求开始
  2. 登录REST API将处理所有此类请求
  3. 它接受auth参数(API密钥,uid / pwd或您选择的任何内容)并验证用户存储(LDAP,AD或MySQL DB等)的身份验证
  4. 如果已验证,则创建一个身份验证令牌并将其交还给客户端/呼叫者
  5. 然后,调用者将此auth令牌+请求特定参数与每个后续请求一起发送到其他业务REST API,直到注销或直到租约到期为止

显然,在Way-2中,REST API需要一种方法来识别和信任令牌有效。Login API执行了auth验证,因此目录中的其他REST API需要信任“valet密钥”。

当然,这意味着需要在REST API之间存储和共享身份验证密钥/令牌。这个共享的,可信任的令牌存储库可以是本地/联合的,允许来自其他组织的REST API相互信任。

但我离题了。

关键是,需要维护和共享“状态”(关于客户端的身份验证状态),以便所有REST API都可以创建一个信任圈。如果我们不这样做,即Way-1,我们必须接受必须对进入的任何/所有请求执行认证行为。

执行身份验证是一个资源密集型过程。想象一下,针对每个传入请求,针对您的用户存储执行SQL查询以检查uid / pwd匹配。或者,加密并执行哈希匹配(AWS样式)。从架构上讲,我怀疑每个REST API都需要使用常见的后端登录服务来执行此操作。因为,如果你不这样做,那么你到处乱丢auth代码。一团糟。

层次越多,延迟越多。

现在,采用Way-1并应用于HTM。如果您必须发送uid / pwd / hash或其他任何请求,您的(人类)用户是否真的关心?不,只要你不打扰她每秒抛出auth /登录页面。如果你这样做,祝客户好运。因此,您要做的是将登录信息存储在客户端的某个位置,在浏览器中,在开头,并在每次发出请求时发送。对于(人类)用户,她已经登录,并且“会话”可用。但实际上,她会根据每个请求进行身份验证。

与Way-2相同。您的(人类)用户永远不会注意到。所以没有伤害。

如果我们将Way-1应用于MTM怎么办?在这种情况下,由于它是一台机器,我们可以通过要求它提交每个请求的认证信息来解决这个问题。没人在乎!在MTM上执行Way-2不会引起任何特殊反应; 它是一台该死的机器。它可以少关心!

真的,问题是什么适合你的需要。无国籍状态需要付出代价。付出代价继续前进。如果你想成为一个纯粹主义者,那么也为此付出代价,继续前进。

最后,哲学并不重要。真正重要的是信息发现,演示和消费体验。如果人们喜欢你的API,你就完成了自己的工作。

作者: Kingz 发布者: 23.11.2013 10:19

9

780 作者的声誉

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

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

通过这种方法,我们每隔30分钟就会执行昂贵的加载缓存操作,其中包含用户特定的访问权限详细信息。因此,如果撤消访问权限或授予新访问权限,则需要30分钟才能反映或注销,然后登录。

作者: Saptarshi Basu 发布者: 14.01.2017 01:30

0

885 作者的声誉

2018年10月回答

有效保护任何Web应用程序的提示

如果您想保护您的应用程序,那么您一定要先使用HTTPS而不是HTTP,这样可以确保在您和用户之间建立安全通道,防止嗅探发送给用户的数据并帮助保存数据交换机密。

您可以使用JWT(JSON Web令牌)来保护RESTful API,与服务器端会话相比,这有许多好处,其好处主要在于:

1-更具可扩展性,因为您的API服务器不必为每个用户维护会话(当您有多个会话时,这可能是一个很大的负担)

2- JWT是自包含的并且具有定义用户角色的权利要求,例如他在日期和到期日期间可以访问和发布的内容(之后JWT将无效)

3-更容易处理负载均衡器并且如果您有多个API服务器,因为您不必共享会话数据也不需要配置服务器将会话路由到同一服务器,只要有JWT的请求命中任何服务器,就可以对其进行身份验证并授权

4-减少数据库压力,您不必经常存储和检索每个请求的会话ID和数据

5-如果您使用强密钥对JWT进行签名,则JWT不会被篡改,因此您可以信任JWT中随请求一起发送的声明,而无需检查用户会话以及他是否已获得授权,你可以查看JWT,然后你就可以知道这个用户可以做什么和做什么了。

许多库提供了在大多数编程语言中创建和验证JWT的简单方法,例如:在node.js中最流行的一个是jsonwebtoken

由于REST API通常旨在使服务器保持无状态,因此JWT与该概念更兼容,因为每个请求都是使用自包含的授权令牌(JWT)发送的,而服务器不必跟踪用户会话,而不是使用服务器状态,以便它记住用户和他的角色,但是,会话也被广泛使用并拥有他们的专业人员,您可以根据需要搜索。

需要注意的一件重要事情是,您必须使用HTTPS将JWT安全地传送到客户端并将其保存在安全的地方(例如在本地存储中)。

您可以从此链接了解有关JWT的更多信息

作者: Ahmed Elkoussy 发布者: 15.10.2018 06:16
32x32