Java 理论与实践:有状态 Web 应用程序都有漏洞吗?

来源:互联网 发布:免费的海关数据 编辑:程序博客网 时间:2024/05/22 08:24
Servlets 框架 HttpSession 提供的会话状态管理机制简化了有状态应用程序的创建,但也很容易导致误用。在没有足够协作的情况下,许多 Web 应用程序对可变数据(比如 JavaBeans 类)使用了 HttpSession 这个机制,从而使自身面临大量潜在的并发性危险。

虽然 Java™ 生态系统中存在许多 Web 框架,但它们都直接或间接地基于 Servlets 基础设施。Servlets API 提供大量有用特性,包括通过 HttpSessionServletContext 机制提供的状态管理,它允许应用程序在跨多个用户请求时保持状态。然而,在 Web 应用程序中使用共享状态受一些微妙的(并且大部分没有进行说明)的规则控制着,因此导致许多应用程序无意中触犯了规则。结果是许多有状态 Web 应用程序存在难以发觉的严重缺陷。

范围容器

在 Servlet 规范中,ServletContextHttpSessionHttpRequest 对象被称为 范围容器(Scoped container)。它们都有 getAttribute()setAttribute() 方法,为应用程序存储数据。这些范围容器的区别在于它们的生命周期不同。对于 HttpRequest,数据只在请求期间有效;对于 HttpSession,数据在用户和应用程序的会话期间有效;而对于 ServletContext,数据在应用程序的整个生命周期中都有效。

由于 HTTP 协议是没有状态的,所以范围容器在构造有状态 Web 应用程序时十分有用;servlet 容器负责管理应用程序的状态和数据的生命周期。尽管这个规范没有强调,但需要保证嵌套在会话或应用程序中的容器在某种程度上是线程安全的,因为 getAttribute()setAttribute() 方法随时都可能被不同的线程调用(这个规范没有直接要求这些实现必须是线程安全的,但它们提供的服务实际上提出了这一点)。

范围容器还为 Web 应用程序提供一个潜在的好处:容器可以透明地管理应用程序状态的复制和故障转移。

会话

session 是特定用户和 Web 应用程序之间的一系列请求-响应交换。用户希望 Web 站点记住他的身份验证凭证、购物车的物品,以及在前面的请求中输入到 Web 表单的信息。但核心 HTTP 协议是没有状态的,这意味着必须将所有请求信息存储到请求本身。因此,如果要创建比一个请求-响应周期更长的有用交互,就必须存储会话状态。servlet 框架允许将每个请求与一个会话关联起来,并提供充当值存储库的 HttpSession 接口,用于存储与该会话相关的(键,值)数据项。清单 1 是一段典型的 servlet 代码,它用于在 HttpSession 中存储购物车数据:


清单 1. 使用 HttpSession 存储购物车数据

HttpSession session = request.getSession(true);
ShoppingCart cart = (ShoppingCart)session.getAttribute("shoppingCart");
if (cart == null) {
cart = new ShoppingCart(...);
session.setAttribute("shoppingCart");
}
doSomethingWith(cart);

清单 1 提供的是 servlet 的典型用途;这个应用程序查看是否已将一个对象放到会话中,如果还没有,它将创建一个...







本文转自IBM Developerworks中国

      请点击此处查看全文

 
原创粉丝点击