Nave Ed

  • June 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Nave Ed as PDF for free.

More details

  • Words: 1,376
  • Pages: 4
Need for a Solution Many Web applications contain sensitive data that requires some sort of password protection scheme. The application must always keep the login page intact until the user supplies a valid credential—only then he can visit his authorized area. When the authorized user logs out from the application, any new user (or a recurring visitor) should not be allowed access without providing his valid credentials. To achieve this, when a user visits the application and enters a valid username and password, a session object is created. As it turns out, HTTP basic and form-based authentication approaches do not provide a mechanism for handling logout. The solution therefore is to employ a custom security implementation, as it provides the most flexibility. A common practice in the custom authentication approach is to retrieve user credentials from a form submission and check against the backend security realms such as LDAP (lightweight directory access protocol) or RDBMS (relational database management system). If the supplied credential is valid, the login action saves some object in a Session object (say an HttpSession). This object indicates that the user has logged in to the Web application. The logout action simply involves removing the user’s details or preferences and calling the invalidate() method on the user's HttpSession object.

Example: //... session.removeAttribute("User"); session.invalidate(); //…

For both the login and logout actions to be meaningful at all, all protected JSP pages must first check the user’s identification (say the username) contained in HttpSession (or similar session object) to determine if the user is currently logged in. If HttpSession contains the identification (the username string as an example) - an indication that the user is logged in— the Web application would send to the browsers the dynamic content in the rest of the JSP page.

Notes ➢ The application behaves correctly by preventing the dynamic content of the protected JSP pages, for example the home page or other secure pages, and the logout page from being served if the user has not logged in, or after he has logged out. In other words, assuming the user has not logged in but points the browser to those JSP pages' URLs, the Web application forwards the control flow to the login page with the error message "Session has ended. Please log in.”.

➢ The application does not behave correctly if, after the user has already logged out, he clicks on the Back button to navigate back to the previous pages. The protected JSP pages reappear on the browser even after the session has ended (with the user logging out). However, continual selection of any link on these pages brings the user to the login page with the error message "Session has ended. Please log in.".

Prevent the browsers from caching The root of the problem is the Back button that exists on most modern browsers. When the Back button is clicked, the browser by default does not request a page from the Web server. Instead, the browser simply reloads the page from its cache. This problem is not limited to Java-based (JSP/servlets/Struts) Web applications; it is also common across all technologies and affects PHP-based (Hypertext Preprocessor), ASP-based, (Active Server Pages), and .Net Web applications.

After the user clicks on the Back button, no round trip back to the Web servers or the application servers should take place. The interaction occurs among the user, the browser, and the cache. The caches that sit between the application servers and the browsers can either be a good thing or a bad thing. These caches do in fact offer a few advantages, but that's mostly for static HTML pages or pages that are graphic- or image-intensive. Web applications, on the other hand are more data-oriented. As data in a Web application is likely to change frequently, it is more important to display fresh data than save some response time by going to the cache and displaying stale or out-of-date information. Fortunately, the HTTP "Expires" and "Cache-Control" headers offer the application servers a mechanism for controlling the browsers' and proxies' caches. The HTTP Expires header dictates to the proxies' caches when the page's "freshness" will expire. The HTTP CacheControl header, which is new under the HTTP 1.1 Specification, contains attributes that instruct the browsers to prevent caching on any desired page in the Web application. When the Back button encounters such a page, the browser sends the HTTP request to the application server for a new copy of that page. The descriptions for necessary Cache-Control headers' directives follow:

 

no-cache: forces caches to obtain a new copy of the page from the origin server no-store: directs caches not to store the page under any circumstance

For backward compatibility to HTTP 1.0, the Pragma:no-cache directive, which is equivalent to Cache-Control:no-cache in HTTP 1.1, can also be included in the header's response.

//... response.setHeader("Cache-Control","no-cache"); //Forces caches to obtain a new copy of the page from the origin server response.setHeader("Cache-Control","no-store"); //Directs caches not to store the page under any circumstance

response.setDateHeader("Expires", 0); //Causes the proxy cache to see the page as "stale" response.setHeader("Pragma","no-cache"); //HTTP 1.0 backward compatibility String userName = (String) session.getAttribute("User"); if (null == userName) { request.setAttribute("Error", "Session has ended. Please login."); RequestDispatcher rd = request.getRequestDispatcher("login.jsp"); rd.forward(request, response); } //...

The combination of setting the headers directives and checking for the user’s identification details in the HttpSession objects ensures that the browsers will not cache the JSP page. Also, if the user is not logged in, the JSP page's dynamic content will not be sent to the browsers, but instead the login page will.

The Refresh Issue Selecting the Refresh command from the IE and Avant browsers or resending the data from the Mozilla and FireFox browsers will result in the previous JSP page reappearing on the browsers. Obviously, this is not desirable as it defeats the purpose of the logout action. When this happens, the implication is a malicious user can still access someone else's data. This problem, however, only manifests itself when the browsers, as a result of the Back button, return to a page that was the action target of a POST request. Tracking the last logon time The above problem occurs because the browsers resubmit the data from their cache. In this case, the data consists of the username and password. Despite displaying a security warning message, as in the case of IE, the browsers in fact create an opposite effect. To fix this problem, the login page should contain—in addition to the username and password—a hidden field called lastLogon that is dynamically initialized with a long value. This long value is obtained by calling System.currentTimeMillis() and denotes the current number of milliseconds since January 1, 1970. When the form in the login page is submitted, the value from this field is first compared against the lastLogon field's value in the User database table. Only when the lastLogon value from the form is greater than the value in the database will it be considered a valid login. For valid login, the field lastLogon in the database should be updated with the form's value to update the lastLogon's time. When the browsers resubmit from the cache as in the case above, the form's lastLogon value is not greater than the database's lastLogon value, therefore the control is forwarded back to the login page with an error message stating "Session has ended. Please log in.". //... RequestDispatcher rd = request.getRequestDispatcher("home.jsp"); //Forward to homepage by default

//... if (rs.getString("password").equals(password)) { //If valid password long lastLogonDB = rs.getLong("lastLogon"); if (lastLogonForm > lastLogonDB) { session.setAttribute("User", userName); //Saves username string in the session object stmt.executeUpdate("update USER set lastLogon= " + lastLogonForm + " where userName = '" + userName + "'"); } else { request.setAttribute("Error", "Session has ended. Please login."); rd = request.getRequestDispatcher("login.jsp"); } } else { //Password does not match, i.e., invalid user password request.setAttribute("Error", "Invalid password."); rd = request.getRequestDispatcher("login.jsp"); } //... rd.forward(request, response); //...

To facilitate the above approach, you must track each user's lastLogon time. For the RDBMS security realm, this can be easily accomplished by extending the schema of the User or an equivalent table by adding a column denoting the lastLogon time. LDAP or other security realms require more thought, but the lastLogon approach can certainly work with those realms.

Related Documents

Nave Ed
May 2020 7
Nave Ed
June 2020 5
Nave Mental
October 2019 31
Nave Short
May 2020 15
Nave Madera
November 2019 24
Nave Jivan
November 2019 22