【问题标题】:How to do stateless (session-less) & cookie-less authentication?如何进行无状态(无会话)和无 cookie 身份验证?
【发布时间】:2014-01-02 12:26:30
【问题描述】:

Bob 使用 Web 应用程序来实现某些目标。并且:

  • 他的浏览器正在节食,因此它不支持 cookies
  • Web 应用程序是一种流行的应用程序,它在特定时刻处理大量用户 - 它必须扩展。只要保持会话会限制同时连接的数量,当然会带来不可忽略的性能损失,我们可能希望有一个无会话系统:)

一些重要说明:

  • 我们确实有传输安全HTTPS 及其最好的朋友);
  • 在幕后,Web 应用程序代表当前用户将大量操作委托给外部服务(这些系统确实将 Bob 识别为其用户之一)-这意味着我们必须将 Bob 的凭据转发给他们

现在,我们如何对 Bob 进行身份验证(针对每个请求)? 哪种方式是实现这种事情的合理方式?

  • 通过 HTML 表单隐藏字段使用凭据打 网球...包含凭据(用户名和密码) 和 两个球拍 分别是浏览器和 Web 应用程序。换句话说,我们可以通过表单字段而不是通过 cookie 来回传输数据。在每个 Web 请求中,浏览器都会发布凭据。不过,在单页应用程序的情况下,这可能看起来像在橡胶墙上打壁球,而不是打网球,因为包含凭据的 web 表单 可能会在 网页 的整个生命周期内保持活动状态(并且服务器将被配置为不提供凭据)。
  • 在页面上下文中存储用户名和密码 - JavaScript 变量等。此处需要单页,恕我直言。
  • 基于加密令牌的身份验证。在这种情况下,登录操作将导致生成加密的安全令牌(用户名 + 密码 + 其他内容)。该令牌将返回给客户端,并且即将到来的请求将伴随该令牌。这有意义吗?我们已经有了 HTTPS...
  • 其他...
  • 最后的手段:不要这样做,在会话中存储凭据!会话很好。带或不带 Cookie。

对于前面描述的任何想法,您是否想到了任何网络/安全问题?例如,

  • 超时 - 我们可能会保留一个时间戳以及凭据(时间戳 = Bob 输入他的凭据的时间)。例如。当NOW - timestamp > threshold时,我们可能会拒绝该请求。
  • 跨站点脚本保护 - 应该没有任何不同,对吧?

非常感谢您花时间阅读本文:)

【问题讨论】:

  • 您可以将令牌附加到每个 URL。 ASP.NET 有一个(传统)模式可以做到这一点。这证明它可以工作。
  • 大家都在哪里? :)
  • 我认为您对可用的选项有一个很好的了解。相信你的推理并自己决定。
  • 是像silverlight of flash这样的插件吗?
  • 尝试使用 JSON Web 令牌 (JWT) jwt.io

标签: security authentication session-cookies stateless cookieless


【解决方案1】:

关于登录选项 - 我认为通常您也希望支持访客会话。

因此,如果您想强制登录,加密令牌选项可能会很好。不知何故,它也可能对来宾会议有好处。 在另一个方向上,我会结合将令牌附加到 URL 和网球选项。

请注意,仅在 URL 中发送凭据可能很危险。例如,您可能会通过 HTTP referer 标头泄漏令牌,甚至可能只是检查您的流量或监视您的计算机的人。

另外,即使您可以使用 cookie,我也建议您添加随机令牌或随机验证程序,以保护自己免受跨站请求伪造 (CSRF) 攻击。

【讨论】:

  • 会话是存储在服务器上的状态。该问题要求进行无状态身份验证。
【解决方案2】:

啊,我喜欢这些问题 - 在没有会话的情况下保持会话。

我在申请评估期间看到了多种方法来做到这一点。一种流行的方式是您提到的打网球方式 - 在每个请求中发送用户名和密码以验证用户身份。在我看来,这是不安全的,尤其是在应用程序不是单页的情况下。它也是不可扩展的,特别是如果您想在将来除了身份验证之外还想为您的应用添加授权(尽管我猜您也可以基于登录构建一些东西)

一种流行的,虽然不是完全无状态的机制(假设您有 JavaScript 执行)是在 JavaScript 中嵌入会话 cookie。我内心的安全人员对此大喊大叫,但它实际上可以工作 - 每个请求都有一个 X-Authentication-Token 标头或类似的东西,然后您将其映射到后端的数据库、内存中的文件存储等以进行验证用户。这个令牌可以有你指定的任何时间的超时,如果超时,用户必须重新登录。它具有相当的可扩展性——如果你将它存储在数据库中,执行它的一个 SQL 语句,并且使用正确的索引,它应该花费很少的时间来执行,即使有多个同时用户。不过,这里的负载测试肯定会有所帮助。如果我正确阅读了问题,这将是您的加密令牌机制-尽管,我强烈建议您使用 32 个字符的加密随机令牌,而不是使用用户名 + 密码 + 其他任何东西的组合 - 这样,它就会保持不可预测,但您仍然可以将其与用户 ID 或类似的东西相关联。

无论您最终使用的是哪个,请确保将其安全地发送给您。 HTTPS 可以通过网络保护您,但如果您通过 URL 泄漏会话令牌(或更糟糕的是,通过 URL 泄漏凭据),它不会保护您。我建议使用标头,或者如果这不可行,则每次都通过 POST 请求发送令牌(这意味着用户浏览器上的隐藏表单字段。)使用 POST 请求的后一种方法应该使用 CSRF 防御,只是以防万一,尽管我怀疑使用令牌本身可能是某种 CSRF 防御。

最后但并非最不重要的一点是,确保您在后端有一些机制来清除过期的令牌。这是过去许多应用程序的祸根——一个快速增长的身份验证令牌数据库,似乎永远不会消失。如果您需要支持多用户登录,请确保限制数量,或者对每个令牌设置更短的时间限制。正如我之前所说,负载测试可能是解决这个问题的答案。

我还可以想到其他一些安全问题,但它们过于宽泛,无法在现阶段解决 - 如果您牢记所有使用(和滥用)案例,您应该能够做到公平该系统的良好实施。

【讨论】:

  • 难道你不做播放框架的工作并向用户发送签名的cookie吗?那么对于每个后续请求,是否将该 cookie 发送回服务器?
  • > 他的浏览器正在节食,因此它不支持 cookie。
  • 这些建议是否实际上是无状态/无会话?在您的五个主要段落中(截至 2013-12-19 版的帖子):#1 是介绍性的,#2 提出了额外的 kludgy Web2.0™-有特色的会议,#3 只是告诫,#4 讨论了有状态的含义,而#5 是一个模糊的结尾......这被接受了??它充其量只是切线信息!
猜你喜欢
  • 2014-07-09
  • 2017-08-03
  • 1970-01-01
  • 2010-09-26
  • 1970-01-01
  • 2011-11-12
  • 1970-01-01
  • 2016-06-29
  • 2014-02-16
相关资源
最近更新 更多