Invalidated sessions and SPRING_SECURITY_SAVED_REQUEST causing continuous 403s

Alessandro Ferrucci <[email protected]> Wed, 28 Jan 2015 08:17:29 -0500
Newsgroups gmane.comp.java.springframework.user
Message-ID <CAMgh6pJ1iZP4F8NPZHzx62yyvjmZKkg+4+xkoESrHkuty1kh+g@mail.gmail.com>
Hello -

So I have a spring app with both pages and AJAX.  I have a problem with
invalidated sessions and
SPRING_SECURITY_SAVED_REQUEST causing those saved requests to execute post
re-login.

What happens is that I'll be in a session.  I go into TOMCAT console to
invalidate all my sessions, which causes spring to create a bunch of
sessions with SPRING_SECURITY_SAVED_REQUEST attribute.  Once I hit refresh,
I get taken to the login page,  I re-authenticate, and all those requests
that caused a SPRING_SECURITY_SAVED_REQUEST execute over and over again
with invalid session IDs.  This happens even if I hit log out, and log back
in.

This is causing issues because in my code when I receive a 403, I redirect
to login page, so once users get into this state, they get auto-logged out
continuously, until they either kill their browser, or some even have to
clear the browser cache.

Any idea how to resolve this?  Attached is my Spring security config:

 <beans:bean id="authenticationEntryPoint"
class="mojo.ocs.web.AjaxAwareAuthenticationEntryPoint">
        <beans:constructor-arg name="loginUrl" value="/login"/>
    </beans:bean>

 <beans:bean id="ajaxManagementFilter"
class="mojo.ocs.web.AjaxSessionManagementFilter">
        <beans:constructor-arg index="0">
            <beans:bean id="securityContextRepository"
class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"
/>
        </beans:constructor-arg>
    </beans:bean>

 <!-- ENTRY POINT REF IMPLEMENTATION -->
    <http auto-config="true" use-expressions="true"
access-denied-page="/accessdenied"
entry-point-ref="authenticationEntryPoint">
        <!--</http><http auto-config="true" use-expressions="true"
access-denied-page="/accessdenied">-->
        <!--<request-cache ref="httpSessionRequestCache"/>-->  <!-- NOT
USED -->
        <!--<custom-filter before="ANONYMOUS_FILTER"
ref="ajaxManagementFilter"/>-->
        <!--<intercept-url pattern="/mojologin" access="isAnonymous()"/>-->
<!-- NOT USED -->
        <intercept-url pattern="/loginfailed" access="isAnonymous()"/>
        <intercept-url pattern="/welcome" access="isAuthenticated()" />
        <intercept-url pattern="/" access="isAuthenticated()" />
        <intercept-url pattern="/private_res/**" access="isAuthenticated()"
/>
        <intercept-url pattern="/tne/**" access="isAuthenticated()" />
        <intercept-url pattern="/team_reports/**"
access="isAuthenticated()" />
        <intercept-url pattern="/staff/**" access="isAuthenticated()" />
        <intercept-url pattern="/cases/**" access="isAuthenticated()" />
        <intercept-url pattern="/msgs/**" access="isAuthenticated()" />
        <intercept-url pattern="/lso_reps/**" access="isAuthenticated()" />
        <intercept-url pattern="/alerts/**" access="isAuthenticated()" />
        <intercept-url pattern="/progress/**" access="isAuthenticated()" />
        <intercept-url pattern="/autosuggest/**" access="isAuthenticated()"
/>
        <intercept-url pattern="/perf_qual_report/**"
access="isAuthenticated()" />
        <intercept-url pattern="/aosc_area_coverage/**"
access="isAuthenticated()" />
        <intercept-url pattern="/dir_services/**"
access="isAuthenticated()" />
        <!--<form-login login-page="/login" default-target-url="/welcome"
always-use-default-target="true" authentication-failure-url="/loginfailed"
/>-->
        <form-login login-page="/login" default-target-url="/welcome"
authentication-failure-url="/loginfailed" />
        <logout delete-cookies="JSESSIONID"  logout-success-url="/logout"
invalidate-session="true"/>
        <session-management invalid-session-url="/login"
session-fixation-protection="newSession" />
    </http>

Below is the AjaxSessionManagementFilter, which I tried to comment out to
see if that would solve the issue, it didn't:

public class AjaxSessionManagementFilter extends SessionManagementFilter {

    private static Logger logger =
Logger.getLogger(AjaxSessionManagementFilter.class);

    public AjaxSessionManagementFilter(SecurityContextRepository
securityContextRepository) {
        super(securityContextRepository);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) {
        if (SecurityContextHolder.getContext().getAuthentication() != null)
{
            Object pObj =
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            String ajaxHeader = ((HttpServletRequest)
request).getHeader("X-Requested-With");
            boolean isAjax = "XMLHttpRequest".equals(ajaxHeader);
            if (isAjax) {
                if (pObj instanceof String) {
                    if (((String) pObj).equals("anonymousUser")) {
                        try {
//                             ((HttpServletResponse)
response).sendRedirect("/login");
                            ((HttpServletResponse)
response).sendError(HttpServletResponse.SC_FORBIDDEN, "Ajax REquest Denied
(Session Expired)");
                        } catch (IOException ex) {
                            logger.error(ex.getMessage(), ex);
                        }
                    }
                }
            }
            try {
                super.doFilter(request, response, chain);
            } catch (IOException ex) {
                logger.error(ex.getMessage(), ex);
            } catch (ServletException ex) {
                logger.error(ex.getMessage(), ex);
            } catch
(org.springframework.security.access.AccessDeniedException ex) {
                try {
                    ((HttpServletResponse)
response).sendError(HttpServletResponse.SC_FORBIDDEN, "Ajax REquest Denied
(Session Expired)");
                } catch (IOException ex1) {
                    logger.error(ex1.getMessage(), ex1);
                }
            }
        }else{
            try {
                super.doFilter(request, response, chain);
            } catch (IOException ex) {
                logger.error(ex.getMessage(), ex);
            } catch (ServletException ex) {
                logger.error(ex.getMessage(), ex);
            }
        }
    }
}


And my 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 {

        boolean isAjax
                =
"XMLHttpRequest".equals(request.getHeader("X-Requested-With"));

        if (isAjax) {
            response.sendError(403, "Forbidden");
        } else {
            super.commence(request, response, authException);
        }
    }
}
Any hints?  perhaps turning off the  SPRING_SECURITY_SAVED_REQUEST will
completely solve it, and I'm open to that as well.

thanks
Alessandro Ferrucci

------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/

_______________________________________________
Springframework-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/springframework-user