{"id":1737,"date":"2016-09-23T14:13:36","date_gmt":"2016-09-23T14:13:36","guid":{"rendered":"http:\/\/codethataint.com\/blog\/?p=1737"},"modified":"2016-09-23T14:14:01","modified_gmt":"2016-09-23T14:14:01","slug":"how-to-prevent-user-from-seeing-previously-visited-secured-page-after-logout","status":"publish","type":"post","link":"https:\/\/codethataint.com\/blog\/how-to-prevent-user-from-seeing-previously-visited-secured-page-after-logout\/","title":{"rendered":"How to Prevent user from seeing previously visited secured page after logout"},"content":{"rendered":"<p>The problem is that the requested page is been loaded from the browser cache instead of straight from the server. You just need to instruct the browser to not cache all the restricted JSP. This way the browser is forced to request the page from the server instead of from the cache and hence all login checks on the server will be executed. <\/p>\n<p>You can do this using a Filter which sets the necessary response headers in the doFilter() method:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@WebFilter\r\npublic class NoCacheFilter implements Filter \r\n{\r\n    @Override\r\n    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException \r\n   {\r\n        HttpServletResponse response = (HttpServletResponse) res;\r\n        response.setHeader(&quot;Cache-Control&quot;, &quot;no-cache, no-store, must-revalidate&quot;);       \r\n        response.setHeader(&quot;Pragma&quot;, &quot;no-cache&quot;); \/\/ HTTP 1.0.\r\n        response.setDateHeader(&quot;Expires&quot;, 0); \/\/ Proxies.\r\n        chain.doFilter(req, res);\r\n    }\r\n    \/\/ ...\r\n}\r\n<\/pre>\n<p>Map this Filter on an url-pattern of interest, for example *.jsp.<\/p>\n<pre>\r\n@WebFilter(\"*.jsp\")\r\n<\/pre>\n<p>Or if you want to put this restriction on secured pages only, then you should specify an URL pattern which covers all those secured pages. For example, when they are all in the folder \/app, then you need to specify the URL pattern of \/app\/*. <\/p>\n<pre>\r\n @WebFilter(\"\/app\/*\")\r\n<\/pre>\n<p>Even more, you can do this job in the same Filter as where you&#8217;re checking the presence of the logged-in user.<\/p>\n<p><strong>Complete Authentication Filter<\/strong><br \/>\nThe filter (the interceptor) shouldn&#8217;t check the validity of the username\/password combo. That&#8217;s the responsibility of the servlet (the controller).<\/p>\n<p>The filter should merely check if the user is logged-in or not (usually by just checking the presence of a session attribute) and then continue the request or block it by redirecting back to the login page.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@WebFilter(&quot;\/*&quot;)\r\npublic class LoginFilter implements Filter {\r\n\r\n    @Override\r\n    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {    \r\n        HttpServletRequest request = (HttpServletRequest) req;\r\n        HttpServletResponse response = (HttpServletResponse) res;\r\n        HttpSession session = request.getSession(false);\r\n        String loginURI = request.getContextPath() + &quot;\/login&quot;;\r\n\r\n        boolean loggedIn = session != null &amp;&amp; session.getAttribute(&quot;user&quot;) != null;\r\n        boolean loginRequest = request.getRequestURI().equals(loginURI);\r\n\r\n        if (loggedIn || loginRequest) {\r\n            chain.doFilter(request, response);\r\n        } else {\r\n            response.sendRedirect(loginURI);\r\n        }\r\n    }\r\n\r\n    \/\/ ...\r\n}\r\n<\/pre>\n<p>The servlet should collect the submitted data, find the associated User in database and if found then store it as a session attribute and then redirect to the home page, else redisplay the form with validation errors.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@WebServlet(&quot;\/login&quot;)\r\npublic class LoginServlet extends HttpServlet {\r\n\r\n    @EJB\r\n    private UserService userService;\r\n\r\n    @Override\r\n    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {\r\n        request.getRequestDispatcher(&quot;\/WEB-INF\/login.jsp&quot;).forward(request, response);\r\n    }\r\n\r\n    @Override\r\n    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {\r\n        String username = request.getParameter(&quot;username&quot;);\r\n        String password = request.getParameter(&quot;password&quot;);\r\n        Map&lt;String, String&gt; messages = new HashMap&lt;String, String&gt;();\r\n\r\n        if (username == null || username.isEmpty()) {\r\n            messages.put(&quot;username&quot;, &quot;Please enter username&quot;);\r\n        }\r\n\r\n        if (password == null || password.isEmpty()) {\r\n            messages.put(&quot;password&quot;, &quot;Please enter password&quot;);\r\n        }\r\n\r\n        if (messages.isEmpty()) {\r\n            User user = userService.find(username, password);\r\n\r\n            if (user != null) {\r\n                request.getSession().setAttribute(&quot;user&quot;, user);\r\n                response.sendRedirect(request.getContextPath() + &quot;\/home&quot;);\r\n                return;\r\n            } else {\r\n                messages.put(&quot;login&quot;, &quot;Unknown login, please try again&quot;);\r\n            }  \r\n        }\r\n\r\n        request.setAttribute(&quot;messages&quot;, messages);\r\n        request.getRequestDispatcher(&quot;\/WEB-INF\/login.jsp&quot;).forward(request, response);\r\n    }\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>The problem is that the requested page is been loaded from the browser cache instead of straight from the server. You just need to instruct the browser to not cache all the restricted JSP. This way the browser is forced to request the page from the server instead of from the cache and hence all&hellip; <a href=\"https:\/\/codethataint.com\/blog\/how-to-prevent-user-from-seeing-previously-visited-secured-page-after-logout\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[194],"tags":[],"class_list":["post-1737","post","type-post","status-publish","format-standard","hentry","category-sessions"],"_links":{"self":[{"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/posts\/1737","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/comments?post=1737"}],"version-history":[{"count":1,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/posts\/1737\/revisions"}],"predecessor-version":[{"id":1738,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/posts\/1737\/revisions\/1738"}],"wp:attachment":[{"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/media?parent=1737"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/categories?post=1737"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/tags?post=1737"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}