如何进行无状态(无会话)和无 cookie 身份验证?

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

  • 他的浏览器正在节食,因此它不支持 饼干
  • Web 应用程序是一个流行的应用程序,它在一个给定的时刻处理大量的用户-它必须 规模很好。只要保持会话将强制 对同时连接的数量的限制,当然,将带来一个不可忽略的 表现罚款,我们可能希望有一个无会话的系统:)

一些重要的注释:

  • 我们有 transport security(HTTPS和它最好的朋友) ;
  • 在幕后,Web 应用程序在当前的 user's behalf上将大量操作委托给 external services(这些系统确实将 Bob 作为其用户之一)——这意味着 we have to forward them Bob's credentials

现在,我们如何验证 Bob (对每个请求) ? 哪种方式才是实现这一目标的合理途径呢?

  • 通过 HTML 表单隐藏字段使用凭证播放 网球... 包含凭证(用户名和密码) ,而 两个球拍分别是浏览器和 Web 应用程序。换句话说,我们可以通过表单字段来回传输数据,而不是通过 cookie。在每个 Web 请求中,浏览器都会发布凭据。虽然,在 单页应用的情况下,这可能看起来像在橡胶墙上播放 南瓜,而不是在播放 网球,因为包含凭证的 网上表格可能会在 网页的整个生命周期中保持活跃(并且服务器将被配置为不提供凭证)。
  • storing the username & the password in the context of the page - JavaScript variables etc. Single-page required here, IMHO.
  • 基于加密令牌的认证。在这种情况下,登录操作将导致生成加密的安全令牌(用户名 + 密码 + 其他东西)。这个令牌将被服务回客户端,即将到来的请求将伴随这个令牌。这说得通吗?我们已经有 HTTPS 了。
  • 其他人。
  • 最后一招: 不要这样做,在会话中存储凭据! 会话是好的。有或没有 cookie。

Does any web / security concern come into your mind, regarding any of the previously described ideas? For example,

  • Time-outing -我们可以保留一个 时间戳,以及凭据(时间戳 = Bob 输入凭据的时间)。例如,当 NOW - timestamp > threshold,我们可能会拒绝请求。
  • Cross-site scripting protection - should not be different in any way, right?

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

45854 次浏览

关于登录选项——我认为通常您也希望为客人提供会话支持。

因此,如果您想强制登录,加密令牌选项可能是不错的选择。也许对嘉宾会议也有好处。 在另一个方向上,我将结合将令牌追加到 URL 和网球选项。

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

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

啊,我喜欢这些问题——维持一个没有会议的会议。

在应用程序评估期间,我已经看到了多种实现这一点的方法。其中一种流行的方法是您提到的 打网球方法——在每个请求中发送用户名和密码以验证用户。在我看来,这是不安全的,特别是当应用程序不是单页的时候。它也是不可伸缩的,特别是如果你想在将来除了身份验证之外再给你的应用添加授权(尽管我猜你也可以基于登录构建一些东西)

One popular, although not completely stateless mechanism (assuming you have JavaScript execution) is to embed the session cookie in the JavaScript. The security guy in me is screaming at this, but it could actually work - every request has a X-Authentication-Token header or something like that, and you map that to a database, file-store in memory, etc. on the backend to validate the user. This token can have a timeout of whatever time you specified, and if it times out, the user has to log in again. It's fairly scalable - if you store it in a database, its one SQL statement executed, and with the correct indexes, it should take very little time to execute, even with multiple simultaneous users. Load testing here would definitely help though. If I read the question correctly, this would be your encrypted token mechanism - although, I would strongly suggest that you use a cryptographically random token of say 32 characters, versus using a combination of username + password + whatever else - this way, it stays unpredictable, but you can still associate it with the user ID or some such thing.

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

Last, but not the least, make sure you have some mechanism in the backend to purge expired tokens. This has been the bane of many applications in the past - a rapidly growing database of authentication tokens which never seems to go away. If you need to support multiple user logins, make sure you either limit the number, or have a shorter time limit on each token. As I said before, load testing may be the answer to this.

我可以想到一些其他的安全问题,但是它们太广泛了,在这个阶段无法解决——如果您牢记所有的使用(和滥用)情况,您应该能够很好地实现这个系统。