Spring security custom filter called multiple times

kmansoor picture kmansoor · Mar 26, 2015 · Viewed 16.9k times · Source

I have a custom logout filter called six times. Twice as soon I try to access the application, twice when I enter username/password and click on 'Login' and then twice again when I click on 'logout'.

What am I doing wrong?

Configuration:

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN_FUNCTIONS')" />      
    <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />

    <form-login login-page="/login"
        authentication-success-handler-ref="customAuthenticationSuccessHandlerBean"
        authentication-failure-handler-ref="customAuthenticationFailureHandlerBean" />
    <logout invalidate-session="true" success-handler-ref="logoutHandlerBean" />
    <session-management session-fixation-protection="migrateSession">
        <concurrency-control max-sessions="1"
            expired-url="/login_sessionexpired" />
    </session-management>

    <custom-filter before="LOGOUT_FILTER" ref="customLogoutFilter" />
</http>

<beans:bean id="customLogoutFilter" class="com.hurontg.libms.security.CustomLogoutFilter" />

The filter:

public class CustomLogoutFilter extends OncePerRequestFilter {
/**
 * 
 */
private XLogger logger = XLoggerFactory
        .getXLogger(CustomLogoutFilter.class.getName());

@Override
protected void doFilterInternal(HttpServletRequest req,
        HttpServletResponse res, FilterChain chain)
        throws ServletException, IOException {

    logger.error("========================================================================================");
    logger.error("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ Custom Logout Filter $$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
    logger.error("========================================================================================");

    chain.doFilter(req, res);
}

}

Spring version: 4.1.1 Spring security: 3.2.5

Answer

mikeapr4 picture mikeapr4 · Jul 22, 2015

If you are using Spring Boot, any GenericFilterBean (OncePerRequestFilter is one) in the context will be automatically added to the filter chain. Meaning the configuration you have above will include the same filter twice.

The easiest workaround for this is to define a FilterRegistrationBean in the context, and have it disabled:

<beans:bean id="customLogoutFilterRegistration" class="org.springframework.boot.context.embedded.FilterRegistrationBean">
    <beans:property name="filter" ref="customLogoutFilter"/>
    <beans:property name="enabled" value="false"/>
</beans:bean>