gpt4 book ai didi

java - 如何在 Java EE 中隔离用户 session ?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:50:55 24 4
gpt4 key购买 nike

我们正在考虑在 Java EE 中开发一个关键任务应用程序,给我留下深刻印象的一件事是该平台缺乏 session 隔离。让我解释一下这个场景。

我们有一个 native Windows 应用程序(一个完整的 ERP 解决方案),每月从稀疏的贡献者那里收到大约 2k LoC 和 50 个错误修复。它还支持脚本,因此客户可以添加自己的逻辑,而我们不知道这样的逻辑是做什么的。每个服务器节点都有一个代理和一个进程池,而不是使用线程池。代理接收客户端请求,将其排入队列直到池中的实例空闲,将请求发送到该实例,将响应传递给客户端,然后将实例释放回进程池。

这种架构非常健壮,因为有如此多的稀疏贡献和自定义脚本,部署版本出现一些严重错误的情况并不少见,例如无限循环、长时间等待的悲观锁、内存损坏或内存泄漏。我们实现了内存限制、请求超时和一个简单的看门狗。每当某个进程无法正确及时地回答时,代理就会将其杀死,因此看门狗会检测并启动另一个实例。如果进程在开始响应请求之前崩溃,代理会将相同的请求发送到另一个池化实例,并且用户不知道服务器端的任何故障(管理日志除外)。这很好,因为某些实例在处理请求时会被伪造的代码慢慢破坏。因为大多数 session 数据保存在客户端或(在极少数情况下)保存在共享存储中,所以它似乎可以完美地工作。

现在考虑转向 Java EE,我在规范或流行的应用程序服务器(如 Glassfish 和 JBoss)中找不到任何类似的东西。是的,我知道大多数集群实现都通过 session 复制进行透明的故障转移,但是我们有一些小公司在一个简单的 2 节点集群上使用我们的系统(我们也有一些冒险家在 1 节点服务器上使用该系统) .对于线程池,我知道有问题的线程会导致整个节点宕机,因为服务器无法检测并安全地杀死它。关闭整个节点比终止单个进程要糟糕得多 - 我们的部署中每个节点都有大约 100 个池化进程实例。

我知道IBM和SAP都知道这个问题,基于

,分别。但根据最近的 JSR、论坛和开源工具,社区上没有太多 Activity 。

问题来了!

  1. 如果您有类似的情况并且使用Java EE,你是怎么解决的?

  2. 你知道即将到来的开源产品或改变可以解决这个问题的 Java EE 规范问题?

  3. .NET 有同样的问题吗?能你解释或引用引用资料?

  4. 你知道一些现代和可以解决这个问题的开放平台问题和值得做的任务ERP业务逻辑?

拜托,我不得不请你不要谈论进行更多测试或任何类型的 QA 投资,因为我们不能强制我们的客户在他们自己的脚本上进行此操作。我们也有紧急错误修复必须绕过 QA 的情况,虽然我们强制客户接受这一点,但我们不能让他接受有错误的软件部分会影响一系列不相关的功能。这是关于稳健架构的问题,而不是开发过程。

感谢您的关注!

最佳答案

您偶然发现的是关于使用 Java 和“恶意”应用程序的基本问题。

这不仅是 Java EE 级别的基本问题,也是核心 JVM 级别的基本问题。可用的典型 JVM 在加载“不安全代码”方面存在各种问题。从内存泄漏、类加载器泄漏、资源耗尽到不干净的线程终止,典型的 JVM 根本不够健壮,无法在共享环境中很好地处理行为不当的代码。

一个简单的例子就是Java堆的内存耗尽。作为一个基本规则,NOBODY(没有人,我特别指的是核心 Java 库和几乎所有其他第 3 方库)捕获 OutOfMemory 异常。很少有人这样做,但即使是他们也无能为力。典型的代码处理他们“期望”处理的异常,但让其他人失败。运行时异常(OOM 就是其中之一)会愉快地通过调用堆栈一直冒到顶部,留下未经检查的关键路径代码的残骸,让所有事情都处于未知状态。

诸如“不会失败”的构造函数或静态初始化器之类的东西留下了“永不为空”的未初始化类成员。这些损坏的类根本不知道它们已损坏。没有人知道它们已经损坏,也没有办法清理它们。出现 OOM 的堆是一个不安全的镜像,几乎需要重新启动(当然,除非您自己编写或审核了所有代码,当然,您不会这样做——谁会这样做呢?)。

现在,很可能会有特定于供应商的 JVM,它们的性能更好,可以让您更好地控制。基于 Sun/Oracle JVM 的那些(即大多数)没有。

因此,这不一定是 Java EE 问题,而是 JVM 问题。

在 JVM 中托管恶意代码不是一个好主意。唯一可行的方法是,如果您拥有一种脚本语言,并且该脚本语言实现了某种资源控制。这是可以做到的,并且您可以调整现有的作为开始(JavaScript、Groovy、JPython、JRuby)。这些语言允许用户直接访问 Java 库的事实使它们具有潜在的危险,因此您可能还必须将其限制为仅由脚本处理程序包装的方面。不过,此时“为什么要使用 Java”的问题浮出水面。

您会注意到 Google App Engine 不执行这些操作。它为正在运行的每个应用程序创建一个单独的 JVM,但即便如此,它也极大地限制了在这些 JVM 中可以执行的操作,特别是通过现有的 Java 安全模型。这里的区别在于,这些实例往往是“长期存在的”,以免承受启动和关闭的处理成本。我应该说,它们应该长寿,而那些长寿的确实会产生这些成本。

您可以自己创建多个 JVM 实例,为它们提供一些基础设施来处理逻辑请求,为它们提供自定义类加载器逻辑以尝试防止类加载器泄漏,并尽可能地让您终止实例(它们'只是一个过程)如果你愿意的话。这可以工作,并且可能工作“正常”,具体取决于调用的粒度以及您的逻辑的“启动”时间。启动时间至少是从运行到运行的逻辑类的加载时间,仅此一项就可能使这成为一个坏主意。它肯定不会是“Java EE”。 Java EE 不是为了做这种事情而设置的。但是您也不清楚您正在查看的 Java EE 功能是什么。

实际上,这就是 Apache 和“mod_php”所做的。多个实例,作为进程,单独处理请求,一旦表现不佳就会在必要时被杀死。这就是 PHP 在共享主机业务中很常见的原因。在这种结构中,基本上是“安全”的。

关于java - 如何在 Java EE 中隔离用户 session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5251609/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com