在 JSP 中处理页面导航的最佳策略

发布于 2024-11-15 12:03:32 字数 567 浏览 1 评论 0原文

我正在探索JSP来实现动态网页。要解决的一个问题是页面之间的导航。用户可以在浏览器中后退和前进。

这必须处理。例如,如果有人注销,我们不希望其他人通过单击“返回”来检索会话或数据。另一个例子是我们不想重新提交表单两次。

我正在寻找解决页面导航问题的提示和建议。我想创建一个必须处理的问题列表+可能的解决方案:

问题:

  • 确保会话不能通过后退/前进点击来检索/劫持
  • 确保表单不会提交
  • 两次确保用户无法篡改 cookie 或 URL 数据或隐藏字段来破坏控制流和安全性

解决方案:

  • 实现访问过的页面堆栈
  • 当调用页面时,在其显示时进行注册,以区分来自“的新请求”返回'
  • 控制当前会话

P.S.:我见过这个问题,但没有真正的答案。

I am exploring JSP to implement dynamic web pages. One issue to solve is navigation between pages. Users have the possibility to go back and forward in their browsers.

This has to be handled. If someone logs out (for example), we don't want someone else to retrieve the session or data by clicking 'go back'. Another example is that we don't want to resubmit forms twice.

I am looking for tips and advices to solve page navigation issues. I would like to create a list of issues one has to take care of + possible solutions:

Issues:

  • Making sure sessions cannot be retrieved/hijacked with go back/forward clicks
  • Making sure forms and not submitted twice
  • Making sure users cannot fiddle cookies or URL data or hidden fields to break control flow and security

Solutions:

  • Implement a stack of visited pages
  • When a page is invoked, register the moment it is displayed to differentiate new requests from 'go back'
  • Control current session

P.S.: I have seen this question, but there is no real answer to it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

無心 2024-11-22 12:03:32

确保会话不会被后退/前进点击检索/劫持

只需 禁用这些页面的浏览器缓存。另请参阅防止用户在注销后看到以前访问过的安全页面。


确保表单不提交两次

生成一个长的、唯一的且无法猜测的字符串,将其存储在会话中......

String token = UUID.randomUUID().toString();
((Set<String>) session.getAttribute("tokens")).add(token);
request.setAttribute("token", token);
request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response);

并作为表单的隐藏输入字段。

<input type="hidden" name="token" value="${token}" />

提交后,比较并删除会话中的密钥。如果它在会话中,则继续提交。

if (((Set<String>) session.getAttribute("tokens")).remove(request.getParameter("token")) {
    // Valid token. Proceed with submit.
} else {
    // Invalid token. Possible double submit.
}

确保用户无法篡改 Cookie 或 URL 数据或隐藏字段来破坏控制流和安全性

只需自己编写可靠的代码或使用现有且可靠的 MVC 框架,例如 JSF2、Spring- MVC、Struts2等


解决方案:

  • 实现访问过的页面堆栈
  • 当调用页面时,在其显示时进行注册,以区分新请求和“返回”
  • 控制当前会话

很麻烦。

Making sure sessions cannot be retrieved/hijacked with go back/forward clicks

Just disable browser cache of those pages. See also Prevent user from seeing previously visited secured page after logout.


Making sure forms and not submitted twice

Generate a long, unique and impossible-to-guess string, store it in both the session ..

String token = UUID.randomUUID().toString();
((Set<String>) session.getAttribute("tokens")).add(token);
request.setAttribute("token", token);
request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response);

.. and as a hidden input field of the form.

<input type="hidden" name="token" value="${token}" />

Upon submit, compare and remove the key in the session. If it was in the session, then proceed with submit.

if (((Set<String>) session.getAttribute("tokens")).remove(request.getParameter("token")) {
    // Valid token. Proceed with submit.
} else {
    // Invalid token. Possible double submit.
}

Making sure users cannot fiddle cookies or URL data or hidden fields to break control flow and security

Just write robust code yourself or use an existing and robust MVC framework like JSF2, Spring-MVC, Struts2, etc.


Solutions:

  • Implement a stack of visited pages
  • When a page is invoked, register the moment it is displayed to differentiate new requests from 'go back'
  • Control current session

Cumbersome.

z祗昰~ 2024-11-22 12:03:32

为了防止重复提交,我将使用通过 HttpSession 使用的 Apache Struts 1 示例。

Struts 所做的是生成一个随机令牌,该令牌存储在会话中并添加到表示层 (JSP) 的表单页面中。当用户提交表单时,它会从会话中检查表单给出的令牌是否与会话中找到的会话完全相同。如果为真,则处理该请求,否则为重复提交。

示例:

public class AuthenticationAction extends Action {

    public void displayLogout(ActionMapping mapping, ActionForm form,
                        HttpServletRequest request, HttpServletResponse response) throws Exception {

        saveToken(request);
        return mapping.findForward("displayLogout");
    }

    public ActionForward doLogout(ActionMapping mapping, ActionForm form,
                        HttpServletRequest request, HttpServletResponse response) throws Exception {

        if (isValidToken(request)) {
            //It wasn't yet a double submission, delete token generated by Struts
            resetToken(request);
            //logout.
            ...
            //return back home
            return mapping.findForward("home");
        } else {
            //Double submission..
            throw new Exception("double submission");
        }
    }
}

此处可以找到更好的教程。

To prevent double submission, I will use an example Apache Struts 1 used by using HttpSession.

What Struts did was to generate a random token that is stored in a session and added in a form page in a presentation layer (JSP). When a user submit a form, it checks from the session to see if the token given by the form is exactly the same session found in the session. If it's true, then process the request else it's a double submission.

Example:

public class AuthenticationAction extends Action {

    public void displayLogout(ActionMapping mapping, ActionForm form,
                        HttpServletRequest request, HttpServletResponse response) throws Exception {

        saveToken(request);
        return mapping.findForward("displayLogout");
    }

    public ActionForward doLogout(ActionMapping mapping, ActionForm form,
                        HttpServletRequest request, HttpServletResponse response) throws Exception {

        if (isValidToken(request)) {
            //It wasn't yet a double submission, delete token generated by Struts
            resetToken(request);
            //logout.
            ...
            //return back home
            return mapping.findForward("home");
        } else {
            //Double submission..
            throw new Exception("double submission");
        }
    }
}

A better tutorial is found here.

街角迷惘 2024-11-22 12:03:32

嗯,如果你愿意,你也可以使用 Spring Webflow 框架,但是使用后退和刷新而不是提交表单两次可以通过定义你的控制器来轻松解决。我认为使用REST也可以帮助解决一些问题。

隐藏字段操作是另一回事,因为隐藏字段始终可以在页面源中查看。如果这个领域可以被观察到,那么它就可以被操纵。

Hmm, you can also use the Spring Webflow framework if you want, but the use of the back and refresh not submitting your forms twice can easely be solved by defining your controller right. I think the use of REST can also help solve some problems.

The hiddenfield manipulation is another thing since a hiddenfield can always be viewed in the source of your page. And if the field can be viewed then it is open to manipulation.

鼻尖触碰 2024-11-22 12:03:32

为了避免重新发明轮子,使用现有的框架似乎是最好的解决方案。 Struts 看起来是一个不错的选择。提供了简单的介绍教程

To avoid re-inventing the wheel, using an existing framework seems to be the best solution. Struts looks like a good candidate. A simple introduction tutorial is available.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文