7

I'm developing a web application, based on Spring-Boot - 1.1.6, Spring -Security -3.2.5 and more.

I'm using Java based configuration:

@Configuration
@EnableWebMvcSecurity
public class SecurityCtxConfig extends WebSecurityConfigurerAdapter {


    @Bean
    DelegatingAuthenticationEntryPoint delegatingAuthenticationEntryPoint() {
        LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> map = new LinkedHashMap<RequestMatcher, AuthenticationEntryPoint>();
        Http403ForbiddenEntryPoint defaultEntryPoint = new Http403ForbiddenEntryPoint();
        map.put(AnyRequestMatcher.INSTANCE, defaultEntryPoint);
        DelegatingAuthenticationEntryPoint retVal = new DelegatingAuthenticationEntryPoint(map);
        retVal.setDefaultEntryPoint(defaultEntryPoint);
        return retVal;
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ExceptionHandlingConfigurer<HttpSecurity> exceptionHandling = http.exceptionHandling();
        exceptionHandling.authenticationEntryPoint(delegatingAuthenticationEntryPoint());
        http.logout().logoutSuccessHandler(new LogoutSuccessHandler() {

            @Override
            public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication arg2)
                    throws IOException, ServletException {
                response.setStatus(HttpServletResponse.SC_OK);
            }
        });
    }

}

The requirement is to return Http status 401 in case that the session cookie is invalid or missing(no matter the reason) I see the InvalidSessionStrategy but I don't find a way to set it on the SessionManagementFilter. Can some one please instract me how to implement my plan or another one that will fulfill the requirement

Modi
  • 2,200
  • 4
  • 23
  • 37

3 Answers3

7

Using SpringBoot this works for me:

@Configuration
@EnableWebSecurity
public class UISecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ...
        http.addFilterAfter(expiredSessionFilter(), SessionManagementFilter.class);
        ...
    }

    private Filter expiredSessionFilter() {
        SessionManagementFilter smf = new SessionManagementFilter(new HttpSessionSecurityContextRepository());
        smf.setInvalidSessionStrategy((request, response) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Session go BOOM!"));               
        return smf;
    }
}
pedorro
  • 3,079
  • 1
  • 24
  • 24
6

We had the exact same problem and I did this hack to solve it (yes I know, this is a hack, therefore the name...). I create a BeanPostProcessor and search for the SessionManagementFilter to reconfigure it...

@Bean
public HackyBeanPostProcessor myBeanPostProcessor() {
    return new HackyBeanPostProcessor();
}

protected static class HackyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // FIXME check if a new spring-security version allows this in an
        // other way (current: 3.2.5.RELEASE)
        if (bean instanceof SessionManagementFilter) {
            SessionManagementFilter filter = (SessionManagementFilter) bean;
            filter.setInvalidSessionStrategy(new InvalidSessionStrategy() {

                @Override
                public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
                }
            });
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}
domi
  • 2,167
  • 1
  • 28
  • 45
0

Since I'm using AspectJ (I mean, compile time weaving and not Spring AOP), it was quite easy to hack the SessionManagementFilter creation by setting my custom InvalidSessionStrategy after the SessionManagementFilter is constructed:

@Aspect
public class SessionManagementAspect {
    private static final Log logger = LogFactory.getLog();

    @AfterReturning("execution( org.springframework.security.web.session.SessionManagementFilter.new(..))&&this(smf)")
    public void creation(JoinPoint pjp, SessionManagementFilter smf) throws Throwable {
        logger.debug("Adding/Replacing the invalid session detection policy to return 401 in case of an invalid session");
        smf.setInvalidSessionStrategy(new InvalidSessionStrategy() {

            @Override
            public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
                logInvalidSession(request, "invalid cookie");
                if (!response.isCommitted())
                    response.sendError(HttpStatus.UNAUTHORIZED.value());
            }
        });
    }
}

If you are not using AspectJ, try adding @Component and add this Aspect to your context, it might work if the SessionManagementFilter is a bean (Since Spring-AOP applias only on spring beans)

Modi
  • 2,200
  • 4
  • 23
  • 37