FullAjaxExceptionHandler не показывает страницу с истекшим сроком действия сеанса на кнопке ajax
Я реализовал Omnifaces FullAjaxExceptionHandler, но проблема в том, что он не работает с ajax-запросами. После окончания сеанса, когда я нажимаю кнопку не-ajax, она работает хорошо. Он перенаправляет пользователя на страницу пользовательских ошибок. Но если кнопка использует ajax, она ничего не делает. Страница просто stucks.
Изменить: я изменил ActionListener на Action и все тот же.
Edit2: Это не дает ошибок. Ни выпуск Apache Tomcat, ни Apache Tomcat Log.
вот моя безопасность spring;
<http auto-config='true' use-expressions="true">
<intercept-url pattern="/login" access="permitAll"/>
<intercept-url pattern="/ajaxErrorPage" access="permitAll"/>
<intercept-url pattern="/pages/*" access="hasRole('admin')" />
<intercept-url pattern="/j_spring_security_check" access="permitAll"/>
<logout logout-success-url="/login.xhtml" />
<form-login login-page="/login.xhtml"
login-processing-url="/j_spring_security_check"
default-target-url="/pages/index.xhtml"
always-use-default-target="true"
authentication-failure-url="/login.xhtml"/>
</http>
Ответы
Ответ 1
Вы отправляете синхронную переадресацию в ответ на запрос ajax (ответ HTTP 302, например, response.sendRedirect()
). Это неправильно. JavaScript ajax engine рассматривает ответ 302 в качестве нового адресата для повторной отправки запроса ajax. Тем не менее, это, в свою очередь, возвращает обычную HTML-страницу ваниль вместо XML-документа с инструкциями, которые часть страницы обновляет. Это запутывает, и поэтому перенаправленный ответ вообще игнорируется. Это точно объясняет симптомы, с которыми вы сталкиваетесь.
С одной и той же проблемой также задают и отвечают следующие близкие вопросы:
В принципе, вам нужно проинструктировать Spring "Безопасность", чтобы выполнить следующую условную проверку:
if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
// JSF ajax request. Return special XML response which instructs JavaScript that it should in turn perform a redirect.
response.setContentType("text/xml");
response.getWriter()
.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
.printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", loginURL);
} else {
// Normal request. Perform redirect as usual.
response.sendRedirect(loginURL);
}
Я, однако, не пользователь Spring, и мне не интересно его использовать, и поэтому я не могу дать более подробный ответ о том, как выполнить эту проверку в Spring Security. Однако я могу сказать, что Apache Shiro имеет ту же проблему, которая объясняется и решается в этой статье в блоге: Сделать Shiro JSF Ajax Aware.
Ответ 2
В файле spring -security (en el archivo de Spring Безопасность)
<beans:bean id="httpSessionSecurityContextRepository" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/>
<!-- redirection strategy -->
<beans:bean id="jsfRedirectStrategy" class="com.mycompany.JsfRedirectStrategy">
<beans:property name="invalidSessionUrl" value="/login.xhtml" />
</beans:bean>
<beans:bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter">
<beans:constructor-arg name="securityContextRepository" ref="httpSessionSecurityContextRepository" />
<beans:property name="invalidSessionStrategy" ref="jsfRedirectStrategy" />
</beans:bean>
<http auto-config='true' use-expressions="true">
<intercept-url pattern="/login" access="permitAll"/>
<intercept-url pattern="/ajaxErrorPage" access="permitAll"/>
<intercept-url pattern="/pages/*" access="hasRole('admin')" />
<intercept-url pattern="/j_spring_security_check" access="permitAll"/>
<logout logout-success-url="/login.xhtml" />
<form-login login-page="/login.xhtml"
login-processing-url="/j_spring_security_check"
default-target-url="/pages/index.xhtml"
always-use-default-target="true"
authentication-failure-url="/login.xhtml"/>
<!-- custom filter -->
<custom-filter ref="sessionManagementFilter" before="SESSION_MANAGEMENT_FILTER" />
</http>
Пользовательская redirectStrategy (La estrategia de redirección personalizada)
public class JsfRedirectStrategy implements InvalidSessionStrategy
{
private static final String FACES_REQUEST = "Faces-Request";
private String invalidSessionUrl;
public void setInvalidSessionUrl(String invalidSessionUrl) {
this.invalidSessionUrl = invalidSessionUrl;
}
public String getInvalidSessionUrl() {
return invalidSessionUrl;
}
@Override
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String contextPath = request.getContextPath();
String urlFinal = contextPath+invalidSessionUrl;
if ("partial/ajax".equals(request.getHeader(FACES_REQUEST))) {
// with ajax
response.setContentType("text/xml");
response.getWriter()
.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
.printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", urlFinal);
} else {
// not ajax
request.getSession(true);
response.sendRedirect(urlFinal);
}
}
работайте для меня.