1

许多 Java PaaSes(例如CloudBees 会话存储)提供会话集群/存储,这样用户在特定请求上被路由到哪个服务器节点都没有关系,所有服务器节点共享相同的存储会话数据,因此任何serve 可以为任何客户端请求提供服务。

我想知道这如何应用于客户端 MVC、单页应用程序(如 GWT 应用程序)。

使用 GWT,大多数应用程序都在客户端作为 JavaScript 执行。通常,客户端访问服务器(通过 GWT-RPC 或 RequestFactory)的唯一时间是客户端需要数据时,在这种情况下,它会对GWTServlet.

共享会话存储的理解是,它适用于HttpServlet客户端(请求)和服务器(响应)之间的来回对话。但这似乎并不真正适用于 GWT 领域。

所以我问:我的 GWT 应用程序可以从上面提到的应用程序会话存储中受益吗?为什么或者为什么不?如果是这样,将非常感谢具体的例子 !提前致谢!

例子:

我有一个允许客户端用户执行某些操作的应用程序:

public class BackOfficeServlet extends HttpServlet {
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) {
        User u = getUserFromRequest(request);
        Action a = getActionFromRequest(request);

        // If the user is allowed to do the action, then do it.
        if(UserActionAuthenticator.actionIsAllowed(u, a))
            a.execute(u, request);
    }
}

如何/在哪里HttpSession添加上面代码示例中不存在的安全性或功能?

4

1 回答 1

1

仅当您使用会话存储一些数据时,使用会话集群才有意义。问你:你需要在服务器端会话中保存一些东西吗?如果响应为否,则也无需使用会话集群。GWT 完全是关于有状态的客户端。大多数时候,您可以通过直接在浏览器中保存会话数据来消除对服务器端会话的需要。我给你一个我不想这样做的例子(在这种情况下会话集群将很有用):

想象一下,您的应用程序是一个后台。每个用户都必须登录并且他可以有不同的角色。通常,带有角色的列表将出现在客户端(能够显示/隐藏一些 UI 控件)和服务器端(链接到会话,在服务器端进行两次相同的检查)。您不能信任来自客户端的角色,因为最终用户可能会直接在浏览器中修改它们(即使在缩小 JS 的情况下这是非常复杂的任务)。在这里您有两个选择:1)使用服务器端会话 2)模拟服务器端会话(在每个 RPC 调用中发送一些自定义会话令牌,然后每次重新加载用户角色)。我更喜欢第一个选项,它使我能够重用 Spring Security 等现有安全库(为我节省大量时间/错误)。

总结一下:

  1. 您有一些敏感的会话数据 -> 将它们存储在服务器会话中 -> 您需要会话集群
  2. 您的会话数据不敏感/您根本没有它们-> 将它们存储在浏览器中/没有库存-> 您不需要会话和会话集群
  3. 您有一些敏感的会话数据-> 将它们存储在服务器端的某个位置,并使用一些自定义会话仿真技术为每个请求重新加载它们-> 您不需要会话集群(但您需要比选项 1 更多的时间)。

编辑。 在上面的代码示例中,您可能会遇到以下潜在问题:

  1. 用户以 user1 身份登录(具有 ROLE_USER 权限)。
  2. 他以某种方式生成带有 user2 内部的请求(具有 ROLE_ADMIN 权限)和一些只有在您具有 ROLE_ADMIN 权限时才能执行的操作。
  3. 这个动作会被执行,即使user1没有相应的权限。

问题的原因是用户对象来自不受信任的来源(请求)并且可以由最终用户修改。我们可以将他存储在服务器端,而不是将他存储在客户端,例如使用服务器端会话:

public class BackOfficeServlet extends HttpServlet {
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) {
        User u = getUserFromSession(request.getSession(false));
        Action a = getActionFromRequest(request);

        if(UserActionAuthenticator.actionIsAllowed(u, a))
            a.execute(u, request);
    }
}

现在我们可以信任用户对象,因为最终用户无法更改会话对象。

于 2013-05-15T14:34:33.223 回答