我已经实现了Omnifaces FullAjaxExceptionHandler,但问题是它无法处理ajax请求。会话到期后,当我点击非ajax按钮时,它运作良好。它将用户重定向到自定义错误页面。但是如果按钮使用ajax,它什么都不做。页面只是卡住了。
编辑:我已将ActionListener更改为Action并且仍然相同。
Edit2:它没有错误。既不是Apache Tomcat输出也不是Apache Tomcat Log。
这是我的春天安全;
<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>
答案 0 :(得分:5)
您正在发送同步重定向作为对ajax请求的响应(使用例如response.sendRedirect()
的HTTP 302响应)。这个不对。 JavaScript ajax引擎将302响应视为重新发送ajax请求的新目标。但是,它反过来返回一个简单的vanilla HTML页面而不是XML文档,其中包含要更新页面部分的指令。这是令人困惑的,因此完全忽略了重定向的响应。这恰恰说明了您所面临的症状。
在以下密切相关的问题中也提出并回答了同样的问题:
基本上,您需要以某种方式指示Spring Security执行以下条件检查:
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有完全相同的问题,在本博客文章中解释和解决了这个问题:Make Shiro JSF Ajax Aware。
答案 1 :(得分:1)
文件spring-security(en el archivo de Spring Security)
<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 estrategiaderedirecciónpersonalizada)
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);
}
}
为我工作。