2

我正在尝试使用支持 ajax 的身份验证入口点来处理会话超时问题。但是在会话过期后收到第一个 AJAX 请求时,不会调用它的开始方法。当 Spring Security 第一次使用登录 url 返回 302 状态时。然后浏览器自动从 Location 标头请求登录页面。但是当另一个后续 AJAX 请求被触发时,我的commence方法AjaxAwareAuthenticationEntryPoint被调用并且服务器将 401 状态返回给客户端。我不确定导致这种奇怪行为的配置有什么问题。我使用的是spring-security3.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>

这是最后两个请求的萤火虫屏幕截图

包含最后两个 AJAX 请求的 firebug 屏幕截图

4

0 回答 0