2

I am trying to handle session timeout problem with an ajax-aware authentication entry point. But it's commence method is not called when first AJAX request is received after session was expired. When for the first time spring security returns 302 status with login url. Then browser requests the login page from Location header automatically. But when another subsequent AJAX request is fired, my commence method of AjaxAwareAuthenticationEntryPoint is called and server returns the 401 status to the client. I am not sure what is wrong with my configuration which is causing this weird behavior. I am using spring-security version 3.1.4.

Below is my AJAX-aware authentication entry point:

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"));
    }
}

And this is my spring-security configuration

<?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>

And this is firebug screen shot for last two requests

Screen shot of firebug containing last two AJAX requests

0 Answers0