Web 应用程序的 RESTful 身份验证 [关闭]

Posted

技术标签:

【中文标题】Web 应用程序的 RESTful 身份验证 [关闭]【英文标题】:RESTful authentication for web applications [closed] 【发布时间】:2010-11-11 09:34:51 【问题描述】:

您好早前已经在this question 上写过这个观察和问题,但后来才注意到这是一个古老而“死”的问题。由于我真的很想从其他人那里获得一些见解,因此我将其作为一个新问题重新发布。

对于如何以RESTful方式进行身份验证的问题,人们普遍热情地喊着“HTTP Authentication”。但是,我怀疑这些人是否曾尝试使用 REST 制作基于浏览器的应用程序(而不是机器对机器的 Web 服务)。 (无意冒犯 - 我只是认为他们从未遇到过并发症)

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

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

here 是一篇非常有见地的文章,它逐点解决了这些问题,但这会导致 很多 特定于浏览器的 javascript 黑客攻击、变通方法到变通方法等等。因此,它也不向前兼容,因此随着新浏览器的发布需要不断维护。我不认为这种简洁明了的设计,而且我觉得这是很多额外的工作和头痛,只是为了让我可以热情地向我的朋友展示我的 REST-badge。

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

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

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

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

我觉得这是一个运行良好的足够解决方案,但我必须承认,我不足以成为安全专家来识别该方案中的潜在漏洞 - 我所知道的是数百个非 RESTful Web 应用程序使用本质上相同的登录协议($_SESSION inphp, HttpSession in j2ee 等)。 cookie 标头内容仅用于处理服务器端资源,就像接受语言可能用于访问翻译资源等一样。我觉得它是一样的,但也许其他人没有?各位,你们怎么看?

【问题讨论】:

【参考方案1】:

一个有趣的问题。我现在正在完成一个 REST API 实现——使用了 mod_rewrite 和 PHP。它使用跨 HTTPS 的 HTTP 基本身份验证。到目前为止,我们正在开发一个 Palm Pre 客户端。开发该客户端的人对于必须跟踪用户凭据以随每个请求提交而有些迟疑。

将 SESSION 作为资源公开的想法很有趣。包括它仍然会违反严格的 RESTful 原则。即使您将 SESSION 作为资源公开,您仍然会使用服务器来跟踪客户端状态。严格遵守 REST 可能需要使用 cookie,因为这是浏览器提供给您的客户端持久内存。问题是,如果您不希望用户与浏览器实现的 HTTP 凭据收集进行交互,那么您需要创建一个 JavaScript(或 FLash?)客户端来管理客户端的 HTTP 请求。

我发现一个有用的工具是 REST Client for Firefox 工具...但即使我在使用它,我仍然会将我的凭据输入到标准浏览器弹出窗口中。

我不得不承认在我的实现中包含了一些技巧。如果您所做的只是使用会话来允许潜在开发人员对 API 进行测试/浏览,或者我认为使用基于会话的身份验证没什么大不了的。我敢肯定,纯粹主义者会不同意。真的,这就是归结为……这本质上是一个学术论点。在现实生活中,你必须做有效的事情。

...在 2012 年 10 月 23 日添加此内容...

RESTful 方法坚持让客户端跟踪自己的状态不仅仅是学术性的。它对可扩展性和暴露资源的可寻址性具有重要意义。当我这么说时,我假设通过客户端状态,我们正在讨论特定于请求用户的属性,这些属性会影响 RESTful 接口发出的响应。 REST 的优势之一是它的可寻址性。当您以任何方式根据请求中未传递的信息做出响应时,您就会开始对此进行调整。只是事后的想法...... 3 年后,哈哈。

【讨论】:

您好,谢谢您的回答!但是,我不同意公开会话意味着您将客户端状态保留在服务器上。会话是“相信知道某个密钥 K 的人就是用户 U”,这显然是服务器持有的一种信念。当然,它不是非常静态的数据,因为会话很快就会失效,但是谁说服务器状态必须是静态的?与 RESTful 购物车系统相比。实际上,我最大的担心是,“拥有密钥 K 意味着服务器认为您的用户 U”对我来说非常不安全,但我不知道如何解决这个问题。 一个非常有趣的观点。尽管如此,RESTful 编程的一个基石是不要求服务器保留客户端/应用程序范围信息。资源请求,“不能利用服务器上存储的任何上下文”。我实际上喜欢这种将客户端状态作为资源的想法,但我仍然认为这明显违反了 REST 原则。 我一直不太明白为什么 RESTful 规范如此坚持无状态,即使涉及到用户身份验证也是如此。也许你可以阐明一些。事实上,我将“违反”的唯一实例是用户身份验证,因为我计划在 Glassfish 之外运行我的 API 并跟踪用户会话。如果会话未打开,客户端会获得相应的返回码,然后他可以通过摘要身份验证提交凭据。一旦他通过身份验证,他就可以进入会话直到会话过期,即每个 REST 请求都不会重新进行身份验证。我认为这是一个合理的妥协 我 100% 支持 REST 中的 one-URI=1-object 范例和其他无状态原则。但要求每个请求重新认证有点不合理,IMO【参考方案2】:

我知道这是一个老问题,但我认为这里的很多问题已经在不同的领域得到解决。特别是,我认为OAuth 2.0 Protocol已经考虑了很多这样的问题;我觉得不够权威,无法在这里提供他们的答案摘要,但是链接的站点有很多不同的用例明确指出,这对于这个问题似乎非常有用,即使完整的 OAuth 2.0 不是真的必要在这里。

【讨论】:

以上是关于Web 应用程序的 RESTful 身份验证 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Java Restful Web Services (jax rs) 身份验证模式

Spring RESTful Web 服务身份验证

使用 Apache Shiro 的 Restful Web 服务身份验证和授权

我们自己的“前端 Web 应用程序”和“第三方自定义应用程序”可以针对 RESTful 后端进行身份验证吗?

访问 RESTful Web 服务的最佳身份验证机制

WCF、RESTful Web 服务和自定义身份验证