JSF редирект после истечения времени ожидания сеанса всегда переходит на страницу входа
Дело в том, что у меня есть набор страниц ошибок, и я настроил свое приложение на их использование, но после истечения времени ожидания сеанса оно всегда переходит на страницу входа, а после входа пользователя появляется страница ошибки (которая должен был появиться перед страницей входа).
Вот мои настройки аутентификации:
<security-constraint>
<display-name>SecurityConstraints</display-name>
<web-resource-collection>
<web-resource-name>MyCollection</web-resource-name>
<description/>
<url-pattern>/faces/web/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description />
<role-name>*</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>ApplicationRealm</realm-name>
<form-login-config>
<form-login-page>/login.xhtml</form-login-page>
<form-error-page>/loginFailed.xhtml</form-error-page>
</form-login-config>
</login-config>
<security-role>
<description>All Users</description>
<role-name>*</role-name>
</security-role>
Который должен включать только страницы в / Faces/ Web/, и это похоже на работу, так как я могу посещать страницы ошибок без входа в систему.
Это мое дерево файлов:
WebContent
|
errorpages/
web/
login.xhtml
loginFailed.xhtml
Я использую JSF 2.2.8 с сервером WildFly 8
Ошибка возникает после асинхронного вызова, который обрабатывается ExceptionHandler:
package com.comanage.web.exceptions;
import javax.faces.FacesException;
import javax.faces.application.ViewExpiredException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
/**
* A custom Exception Handler to give special treatment to any given exception
*/
public class ViewExpiredExceptionHandler extends ExceptionHandlerWrapper {
private ExceptionHandler wrapped;
public ViewExpiredExceptionHandler(ExceptionHandler wrapped) {
this.wrapped = wrapped;
}
@Override
public void handle() throws FacesException {
FacesContext facesContext = FacesContext.getCurrentInstance();
for (Iterator<ExceptionQueuedEvent> iter = getUnhandledExceptionQueuedEvents().iterator(); iter.hasNext();) {
Throwable exception = iter.next().getContext().getException();
if (exception instanceof ViewExpiredException) {
HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
if(isAJAXRequest(request)) {
String redirect = "/errorpages/expired.xhtml";
System.out.println("An AJAX request has been detected after the view has expired: Redirecting to \""+redirect+"\"");
String redirectURL = response.encodeRedirectURL(request.getContextPath() + redirect);
StringBuilder sb = new StringBuilder();
sb.append("<partial-response><redirect url=\"").append(redirectURL).append("\"></redirect></partial-response>");
response.setHeader("Cache-Control", "no-cache");
response.setCharacterEncoding("UTF-8");
PrintWriter pw = null;
try {
pw = response.getWriter();
} catch (IOException e) {
e.printStackTrace();
}
pw.println(sb.toString());
pw.flush();
}
else{
facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, "expiredview");
facesContext.renderResponse();
}
iter.remove();
}
}
getWrapped().handle();
}
@Override
public ExceptionHandler getWrapped() {
return wrapped;
}
/**
* Returns true is the request is an AJAX request
* @param request An HttpServletRequest request
* @return True if the request is an AJAX request
*/
private boolean isAJAXRequest(HttpServletRequest request) {
boolean check = false;
String facesRequest = request.getHeader("Faces-Request");
if (facesRequest != null && facesRequest.equals("partial/ajax")) {
check = true;
}
return check;
}
}