RESTful认证

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


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

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

  • 基于HTTPS的HTTP基本认证;
  • Cookies和会话管理;
  • HTTP标头中的令牌(例如OAuth 2.0);
  • 使用附加签名参数查询身份验证
  • 你必须适应甚至更好地混合这些技术,才能最好地与你的软件架构相匹配。

    每个认证方案都有自己的PRO和CON,具体取决于您的安全策略和软件体系结构的目的。

    基于HTTPS的HTTP基本认证

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

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

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

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

    通过Cookies进行会话

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

    一种可能是维护cookie内容中的所有数据。 而且,通过设计,cookie在服务器端得到处理(客户端实际上甚至不会尝试解释这个cookie数据:它只是在每个连续的请求中将它传递回服务器)。 但是这个cookie数据是应用程序状态数据,所以客户端应该在纯粹的无状态世界中管理它,而不是服务器。

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

    cookie技术本身是HTTP链接的,所以它不是真正的RESTful,它应该是协议无关的,恕我直言。 它容易受到MiM或Replay攻击。

    通过令牌授予(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使用。

    查询认证

    查询认证包括通过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)。

    实际上,对于OAuth 2.0即将推出的MAC令牌认证,在“授权令牌”当前计划方面可能是一个巨大的改进。 但这仍然是一项正在进行的工作,并且与HTTP传输有关。

    结论

    值得一提的是,REST不仅仅是基于HTTP的,即使在实践中它大部分都是通过HTTP实现的。 REST可以使用其他通信层。 因此,RESTful认证不仅仅是HTTP认证的同义词,无论Google如何回答。 它甚至不应该使用HTTP机制,而应该从通信层抽象出来。


    我怀疑那些踊跃高喊“HTTP身份验证”的人是否尝试过使用REST制作基于浏览器的应用程序(而不是机器对机器的Web服务)(没有任何意图 - 我只是认为他们没有遇到复杂的问题) 。

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

  • 用户通常会得到一个丑陋的浏览器制作的登录框,这非常不利于用户。 你不能添加密码检索,帮助框等。
  • 注销或以不同名称登录是一个问题 - 浏览器会一直向该站点发送身份验证信息,直到您关闭该窗口
  • 超时很困难
  • 一篇非常有洞察力的文章将逐一解决这些问题,但这会导致很多浏览器特定的javascript hackery,解决方法等变通办法。 因此,它也不是向前兼容的,因此在新浏览器发布时需要不断的维护。 我不认为这是一个干净而清晰的设计,而且我觉得这是一个额外的工作和头痛,所以我可以热情地向我的朋友展示我的REST徽章。

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

    通过仅使用以下规则将会话设置为RESTful资源:

  • 会话将密钥映射到用户ID(可能还有超时的最后一个操作时间戳)
  • 如果会话存在,那就意味着密钥是有效的。
  • 登录意味着发布到/ sessions,新密钥设置为cookie
  • 注销表示DELETEing / sessions / {key}(POST超载,请记住,我们是浏览器,而HTML 5还有很长的路要走)
  • 通过在每个请求中将密钥作为cookie发送并检查会话是否存在并且有效来完成身份验证
  • 与HTTP身份验证唯一的区别在于,身份验证密钥由服务器生成并发送给持续发回的客户端,而不是客户端从输入的凭据中计算出来。

    converter42补充说,当使用https(我们应该)时,重要的是cookie将设置其安全标志,以便认证信息永远不会通过非安全连接发送。 伟大的观点,自己没有看到它。

    我觉得这是一个很好的解决方案,但我必须承认,我不够安全专家来发现此方案中的潜在漏洞 - 我所知道的是,数百个非RESTful Web应用程序使用本质上相同登录协议($ _SESSION inphp,Java EE中的HttpSession等)。 Cookie头内容仅用于寻址服务器端资源,就像接受语言可能用于访问翻译资源等。 我觉得它是一样的,但也许别人没有? 你们觉得怎么样?


    已经有足够多的人在这里谈论这个话题了。 但这是我的2美分。

    有两种交互模式:

  • 人机对话(HTM)
  • 机器对机器(MTM)
  • 该机器是公共分母,表示为REST API,演员/客户机是人或机器。

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

    当我们在人机交互的应用环境中考虑这个问题时,就像Skrebbel在上面指出的那样,“基于浏览器”意味着浏览器中运行的(web)应用程序需要发送它的状态和相关信息制作到后端REST API。

    考虑一下:你有一个公开的数据/信息平台作为一套REST API。 也许你有一个处理所有数据立方体的自助服务BI平台。 但是,您希望您的(人)客户通过(1)Web应用程序,(2)移动应用程序和(3)某个第三方应用程序访问此应用程序。 最后,甚至连锁MTMs导致HTM - 对。 因此,用户仍然处于信息链的顶端。

    在前两种情况下,您有一个人机交互的例子,这些信息实际上是由用户使用的。 在最后一种情况下,您有一个使用REST API的机器程序。

    认证的概念全面适用。 您将如何设计这个以便您的REST API以统一,安全的方式访问? 我看到这个的方式有两种方式:

    方式1:

  • 没有登录开始。 每个请求都会执行登录
  • 客户端发送其标识参数+每个请求的请求特定参数
  • REST API使用它们,转身,ping用户存储(不管是什么)并确认身份验证
  • 如果auth已建立,则为请求提供服务; 否则,用适当的HTTP状态码拒绝
  • 针对目录中所有REST API的每个请求重复上述操作
  • 方法2:

  • 客户端以验证请求开始
  • 登录REST API将处理所有这些请求
  • 它需要身份验证参数(API密钥,uid / pwd或您选择的任何内容)并验证用户存储(LDAP,AD或MySQL DB等)的身份验证。
  • 如果通过验证,则创建一个授权令牌并将其交还给客户端/调用者
  • 然后,调用者将此身份验证令牌+请求特定的参数与其他业务REST API的每个后续请求一起发送,直到退出或直到租约到期
  • 显然,在Way-2中,REST API将需要一种方法来识别和信任令牌为有效的。 Login API执行身份验证验证,因此您的目录中的其他REST API需要信任“代钥”。

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

    但我离题了。

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

    执行认证是一个资源密集型过程。 想象一下,针对每个传入请求,执行SQL查询,针对您的用户存储检查uid / pwd匹配。 或者,加密并执行散列匹配(AWS风格)。 在架构上,每个REST API都需要使用通用后端登录服务执行此操作。 因为,如果你不这样做,那么你在任何地方都会乱授权代码。 一团糟。

    所以更多的图层,更多的延迟。

    现在,采取Way-1并应用于HTM。 您的(人类)用户是否真的关心您是否需要每次发送uid / pwd / hash或其他内容? 不,只要你不打扰她每秒钟的认证/登录页面。 如果你有客户,祝你好运。 因此,您要做的是将登录信息存储在客户端,浏览器中的某个位置,然后将其发送到每个请求。 对于(人)用户,她已经登录,并且“会话”可用。 但事实上,她在每次请求时都会被认证。

    和Way-2一样。 你的(人类)用户永远不会注意到。 所以没有伤害。

    如果我们将Way-1应用于MTM会怎样? 在这种情况下,因为它是一台机器,所以我们可以通过要求它提交每个请求的认证信息来让这个人失望。 没人在乎! 在MTM上执行Way-2不会引起任何特殊反应; 它是一个该死的机器。 它可以小心!

    所以真的,问题是什么适合你的需要。 无国籍有代价。 付出代价并继续前行。 如果你想成为一个纯粹主义者,然后付出代价,然后继续前进。

    最后,哲学并不重要。 真正重要的是信息发现,呈现和消费体验。 如果人们喜欢你的API,你做了你的工作。

    链接地址: http://www.djcxy.com/p/493.html

    上一篇: RESTful Authentication

    下一篇: JavaScript post request like a form submit