客户端会话

8
我希望一些相关的 Web 应用程序客户端能够保持自己的身份验证状态。这样可以提高可伸缩性,因为不需要在群集节点之间进行会话复制。它还使得不同服务器技术(如 Java Servlet 和 PHP)的集成更加容易。
我的计划如下:
1. 在客户端认证后,设置一个带有用户名和会话过期时间的已签名和加密的 cookie。 2. 当客户端发送请求时,服务器解密和验证 cookie,并根据 cookie 值授予或拒绝访问权限。 3. 通过重新设置 cookie 来更新会话过期时间。
所有想要使用会话的服务器只需要知道 cookie 机制和解密密钥即可。参见:客户端层中的会话状态 这种方法可行吗?是否可能将其集成到 Servlet 容器 / 应用程序服务器中,以便对应用程序透明?例如,Servlet 应该能够使用 HttpServletRequest#getRemoteUser()。这是可能的吗?还是我需要像 Spring Security 这样的容器级别的东西?是否有任何现有的客户端会话管理库?
6个回答

8
不是一个好主意。在客户端完全存储诸如会话到期和用户名等重要数据太危险了,无论是否加密。即使这个概念本身在技术上是安全的(我不能深入回答这个问题,因为我不是加密专家),但只需获得您的加密密钥,就可以促进入侵而不损害您的服务器。
拿到密钥的人可以随意生成会话cookie,并冒充任何用户,持续任何时间,这是传统会话概念旨在防止的事情。
对于这个问题,有更好且可扩展的解决方案。例如,为什么不设置一个中央会话验证实例,所有相关的服务器和服务都可以轮询?在网上找找,我100%确定有现成的解决方案来满足您的需求。

虽然这是一个比较老的讨论,但在搜索客户端会话数据信息时仍然排名很高。能够获取会话密钥的人意味着首先可以访问会话数据,因此这个论点并不强。但是,有比使用单个静态密钥更好的策略。而且密钥轮换相对简单易行。该方法面临的最大挑战是确保会话数据包含在客户端的每个相关请求中。 - symcbean

7

我不同意那些说这种方法不安全的海报。正如你所概述的,该方法的变体在许多备受尊敬的框架中使用,例如Rails和Play!,当实现正确时,它是完全安全的。


3
这样可以提高可扩展性,因为不需要在集群节点之间进行会话复制。
首先,即使使用HTTP Session状态复制(某些机制比其他机制更智能,例如WebLogic的{{link1:in-memory replication}}没有太大的开销),使用HTTP Session实际上并不能防止您进行扩展。其次,您真的需要吗?大多数应用程序(大多数)不需要Session复制。第三,我是否理解正确:您计划根本不使用HTTP Session?
在客户端验证后,使用用户名称和会话过期时间设置已签名和加密的cookie。 不要这样做! 不要将服务器使用的用户名和其他敏感数据存储在 cookie 中,这是一个非常糟糕的想法!你需要承认,在某个时间点之前,有人会弄清楚你的系统如何运作并破坏它(特别是如果你的 cookie 可能会受到猜解攻击)。因此,你应该在服务器端的 Session 中存储数据,只在 cookie 中存储 ID,就像实际情况一样。这样更加安全。

这种方法可以吗?

不行。 如果你正在尝试构建可互操作的单点登录系统,则不需要这样做。只需使用集中式身份验证解决方案,例如CASJasig,该方案具有各种技术的库。


我有一个问题。如果我们将sessionID存储在cookie中,并让客户端每次发送到服务器以识别客户端,那么某个坏人是否可以窃取此sessionID并防止用户使用它?这让我感到困惑,因为如果坏人可以从cookie中窃取敏感的id数据,那么sessionID实际上也是敏感的吗?我错了吗?谢谢! - JaskeyLam
我也不同意这里的评论 - 会话复制可能不是很大的开销,但它非常受CAP定理的影响 - 因此请求路由需要与会话管理绑定,这是客户端会话解决的关键问题。客户端会话存在一组不同的问题。我在这里看不到任何建设性的反对意见。 - symcbean

1

这并不是Session的实际实现方式。Cookie本身不需要携带任何会话数据,它只是对其的引用。

Cookie通常保存一个“会话ID”,然后将其链接到服务器上的数据。

如果您没有一个中央数据会话服务器供其他服务器访问,我建议您获取一个 :)


1
这就是他不想做的,因为他希望解决方案是可扩展的。虽然我认为这是唯一的方法。 - Pekka
我想要一个用于身份验证状态的存储。并且我不想将此状态存储在服务器端。我心中有类似于HTTP基本身份验证的想法,但希望更加灵活(例如支持OpenID)。 - deamon

1
在集群环境中,您可以通过使用状态服务器来避免数据的重复 - 该服务器为集群中的所有节点所熟知,并维护所有用户的会话数据。每当用户执行请求时,它都会向应用程序服务器发送一个带有会话ID的cookie;应用程序服务器应从状态服务器检索会话。这对于asp.net开发是可能的,但我不确定Java是否支持这种方法。

1
Java世界必须为此提供解决方案。它是最古老的高级Web平台,被无数企业应用程序使用,在某些时候遇到了同样的问题。 - Pekka

0
正如Pekka所说,这不是一个好主意。有人可以拦截您的cookie并获取敏感会话数据。即使使用SSL,通过使用fiddler2,也可以解密流量。

我并不是指传输层安全协议,而是指对Cookie数据本身进行加密 - 例如使用GnuPG。 - deamon
3
关于 Fiddler2 解密 SSL 流量的问题,你是错误的。这不是 SSL/TLS 设计的漏洞,Fiddler2 只是充当代理,将自己放在可信赖的网络服务器之前,用自动生成的(不受信任的!)证书与发出请求的客户端进行通信,并将其伪装成 HTTPS 客户端,将请求转发到预期的目标。这与说 Fiddler2 可以解密 SSL 流量是非常不同的。如果是这样,犯罪分子昨天就已经把我们的银行账户里的钱取空了。 - Armen Michaeli
@amn:没错,你只是拦截了流量。奇怪的是,在给定的链接中,标题说“解密HTTPS保护的流量”……这是误导性的。它应该是“拦截”。正如Fiddler页面所说,它允许“修改HTTPS安全流量”,因此保持加密的cookie(如deamon所说)仍然不安全,因为有人可以更改实际的加密cookie。 - lmsasu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接