我正在尝试使用支持 ajax 的身份验证入口点来处理会话超时问题。但是在会话过期后收到第一个 AJAX 请求时,不会调用它的开始方法。当 Spring Security 第一次使用登录 url 返回 302 状态时。然后浏览器自动从 Location 标头请求登录页面。但是当另一个后续 AJAX 请求被触发时,我的commence
方法AjaxAwareAuthenticationEntryPoint
被调用并且服务器将 401 状态返回给客户端。我不确定导致这种奇怪行为的配置有什么问题。我使用的是spring-security
3.1.4 版。
下面是我的 AJAX 感知身份验证入口点:
public class AjaxAwareAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
public AjaxAwareAuthenticationEntryPoint(String loginUrl) {
super(loginUrl);
}
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
if (isAjax(request)) {
response.sendError(HttpStatus.UNAUTHORIZED.value(), "Please re-authenticate yourself");
} else {
super.commence(request, response, authException);
}
}
public static boolean isAjax(HttpServletRequest request) {
return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
}
}
这是我的弹簧安全配置
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http auto-config="true" use-expressions="true" entry-point-ref="authenticationEntryPoint">
<intercept-url pattern="/index.jsp" access="permitAll" />
<intercept-url pattern="/qualifiers/**" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/userpreference/**" access="hasRole('ROLE_USER')" />
<!--<intercept-url pattern="/import.do" access="hasRole('ROLE_USER')" />-->
<!-- <anonymous username="guest" granted-authority="ROLE_USER" /> -->
<form-login login-page="/login.jsp" default-target-url="/index.jsp" authentication-success-handler-ref="authSuccessBean" authentication-failure-handler-ref="authFailureBean"
authentication-failure-url="/login.jsp?error=true" always-use-default-target="false" />
<logout logout-success-url="/login.jsp" delete-cookies="JSESSIONID" />
<!-- Spring Security supports rolling tokens for more advanced security needs, but this requires a database to persist the tokens -->
<remember-me />
<session-management invalid-session-url="/login.jsp">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
</http>
<beans:bean id="authenticationEntryPoint" class="com.pcc.myapp.controller.auth.AjaxAwareAuthenticationEntryPoint">
<beans:constructor-arg name="loginUrl" value="/login.jsp" />
</beans:bean>
<authentication-manager>
<authentication-provider user-service-ref="userLoginService">
<!-- <password-encoder hash="sha" /> -->
</authentication-provider>
</authentication-manager>
<beans:bean id="authFailureBean" class="com.pcc.myapp.controller.auth.AuthFailureHandler">
<beans:property name="defaultFailureUrl" value="/login.jsp?error=true" />
</beans:bean>
<beans:bean id="authSuccessBean" class="com.pcc.myapp.controller.auth.AuthSuccessHandler">
<beans:property name="defaultTargetUrl" value="/qualifiers/attributes.do" />
<beans:property name="alwaysUseDefaultTargetUrl" value="true" />
</beans:bean>
</beans:beans>
这是最后两个请求的萤火虫屏幕截图