Best strategy to handle page navigation in JSP
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 开发者_C百科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.
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.
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.
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.
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.
精彩评论