如何在Spring Security中设置自定义无效会话策略

时间:2014-09-12 13:23:04

标签: spring-security

我正在开发一个基于Spring-Boot - 1.1.6,Spring -Security -3.2.5等的Web应用程序。

我正在使用基于Java的配置:

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

}

要求是在会话cookie无效或丢失的情况下返回Http状态401(无论原因) 我看到InvalidSessionStrategy,但我找不到在SessionManagementFilter上设置它的方法。 有人可以告诉我如何实施我的计划或另一个符合要求的计划

3 个答案:

答案 0 :(得分:5)

我们有完全相同的问题,我做了这个黑客来解决它(是的,我知道,这是一个黑客,因此名称......)。 我创建了BeanPostProcessor并搜索SessionManagementFilter以重新配置它...

@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;
    }
}

答案 1 :(得分:4)

使用SpringBoot对我有用:

@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;
    }
}

答案 2 :(得分:0)

由于我正在使用AspectJ(我的意思是编译时编织而不是Spring AOP),通过在{{1}之后设置我的自定义SessionManagementFilter来破解InvalidSessionStrategy创建非常容易。构造:

SessionManagementFilter

如果您没有使用AspectJ,请尝试添加@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()); } }); } } 并将此Aspect添加到您的上下文中,如果@Component是一个bean(因为Spring-AOP applias仅适用于spring bean),它可能会起作用< / p>