Monday 7 April 2014

Container managed security and AJAX

A problem which seems to happen a lot to people using Java form-based security is that if a user gets logged out (eg their session expires), any request they make is forwarded to the login jsp. This means that if the request was made using AJAX it will cause problems because the client will have to handle getting the login page as a response.

My solution here is to use my login page jsp to check whether the request is coming asynchronously and handle it appropriately. I use the URL to differentiate since all my asyncronous servlets are mapped to a URL  with '/ajax/' in the path:

<%@ include file="/taglibs.jsp" %>
<%--Handle AJAX URLs separately--%>
<c:choose>
   <c:when test="${fn:contains(requestScope['javax.servlet.forward.request_uri'],'/ajax/')}">
       <c:set target="${pageContext.response}" property="status" value="401"/>
   </c:when>
   <c:otherwise>
       <%--Return the login page for non-AJAX URLs--%>
       <!DOCTYPE html>
       <html>
           <%--main login page html goes here--%>
       </html>
    </c:otherwise>
</c:choose>

Once the login jsp detects that the response should be asyncronous, it simply sets the http status code of the response to 401 (no permission) which my code on the client handles separately. 
On the client, when 401 is received, the user is notified that they have been logged out, then the page is reloaded, causing the container to redirect them to the login page:

if (xmlHTTP!=null && (xmlHTTP.readyState==4 || xmlHTTP.readyState=="complete")){
   if(xmlHTTP.status==200 || xmlHTTP.status==304){
       //handle correct response here

   }else if(xmlHTTP.status==401){//authentication required
       alert("You've been logged out please press OK to go to the login page.");
       window.location.reload();
   }else{

    //handle other error codes
   }
}

This has the advantage that all once the user logs in, they will be redirected to the original URL they were viewing at the point their session expired. It also means you don't have to write your own login servlet to handle this situation.

No comments:

Post a Comment