ViewExpiredException not thrown on ajax request if JSF page is protected by j_security_check provides the solution when the login page is the JSF page. But what if the login page is a JSP page?
I have a jsp login page:
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/core/login.jsp</form-login-page>
<form-error-page>/core/login.jsp</form-error-page>
</form-login-config>
</login-config>
In my JSF page (facelet), if I click on non-Ajax button, I will be redirected to the login.jsp. If I click an Ajax button, it will remain on the same JSF page. However, in both cases the debugging code that I added to the JSP login page will show up in a console.
===
I re-wrote the login page using a facelet instead of a jsp
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/facelets/login.jsf</form-login-page>
<form-error-page>/facelets/login.jsf</form-error-page>
</form-login-config>
</login-config>
I added an AjaxLoginListener:
public class AjaxLoginListener implements PhaseListener {
@Override
public PhaseId getPhaseId() {
// return PhaseId.ANY_PHASE;
return PhaseId.RESTORE_VIEW;
}
@Override
public void beforePhase(PhaseEvent event) {
System.out.println(" **** AjaxLoginListener: Before Phase: " + event.getPhaseId());
// NOOP.
}
@Override
public void afterPhase(PhaseEvent event) {
System.out.println(" **** AjaxLoginListener: After Phase: " + event.getPhaseId());
FacesContext context = event.getFacesContext();
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
String originalURL = (String) request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
String loginURL = request.getContextPath() + "/facelets/login.jsf";
System.out.println(" **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
+ this.getClass().getName()+" AjaxLoginListener: After Phase: originalURL: " + originalURL + " Login URL: "+loginURL);
System.out.println(" **** AjaxLoginListener: After Phase: request.getRequestURI() " +request.getRequestURI());
System.out.println(" **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
+ this.getClass().getName()+" AjaxLoginListener: After Phase: isAjaxRequest " +context.getPartialViewContext().isAjaxRequest());
if (context.getPartialViewContext().isAjaxRequest()
&& originalURL != null
&& loginURL.equals(request.getRequestURI()))
{
System.out.println(" **** "+new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
+ this.getClass().getName()+" AjaxLoginListener: After Phase: AjaxRequest " + event.getPhaseId());
try {
context.getExternalContext().redirect(originalURL);
} catch (IOException e) {
e.printStackTrace();
throw new FacesException(e);
}
}
}
}
Once I used a facelet instead of a jsp I was able to invoke the listener. However, it never goes to the login page because the originalURL (RequestDispatcher.FORWARD_REQUEST_URI) is always NULL for Ajax requests. What am doing wrong?