0% found this document useful (0 votes)
22 views4 pages

Need For A Solution: Invalidate Method On The User'S Httpsession Object

The document discusses solutions for implementing secure login and logout functionality in web applications. It describes how using session objects can track if a user is logged in, but that HTTP basic and form-based authentication do not provide logout mechanisms. The solution is to use custom security implementations and invalidate session objects on logout. It also addresses issues with browsers caching pages after logout and reloading cached content when the back button is used. To prevent this, the response headers are set to instruct browsers not to cache pages and check for a valid session on protected pages.

Uploaded by

n_choudry
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views4 pages

Need For A Solution: Invalidate Method On The User'S Httpsession Object

The document discusses solutions for implementing secure login and logout functionality in web applications. It describes how using session objects can track if a user is logged in, but that HTTP basic and form-based authentication do not provide logout mechanisms. The solution is to use custom security implementations and invalidate session objects on logout. It also addresses issues with browsers caching pages after logout and reloading cached content when the back button is used. To prevent this, the response headers are set to instruct browsers not to cache pages and check for a valid session on protected pages.

Uploaded by

n_choudry
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 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 Cache-
Control 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.

You might also like