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

Spring security 如何在Spring Security中设置自定义无效会话策略,spring-security,Spring Security,我正在开发一个基于Spring Boot-1.1.6、Spring-Security-3.2.5和更多的web应用程序 我正在使用基于Java的配置: @Configuration @EnableWebMvcSecurity public class SecurityCtxConfig extends WebSecurityConfigurerAdapter { @Bean DelegatingAuthenticationEntryPoint delegatingAuthen

我正在开发一个基于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);
            }
        });
    }

}
@配置
@启用WebMVC安全性
公共类SecurityCxConfig扩展了WebSecurity配置适配器{
@豆子
DelegatingAuthenticationEntryPoint DelegatingAuthenticationEntryPoint(){
LinkedHashMap=新建LinkedHashMap();
Http403禁止入口点defaultEntryPoint=新的Http403禁止入口点();
put(AnyRequestMatcher.INSTANCE,defaultEntryPoint);
DelegatingAuthenticationEntryPoint retVal=新的DelegatingAuthenticationEntryPoint(地图);
retVal.setDefaultEntryPoint(defaultEntryPoint);
返回返回;
}
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
ExceptionHandlingConfigurer exceptionHandling=http.exceptionHandling();
exceptionHandling.authenticationEntryPoint(delegatingAuthenticationEntryPoint());
http.logout().logoutSuccessHandler(新logoutSuccessHandler()){
@凌驾
public void onLogoutSuccess(HttpServletRequest请求、HttpServletResponse响应、身份验证arg2)
抛出IOException、ServletException{
response.setStatus(HttpServletResponse.SC_OK);
}
});
}
}
如果会话cookie无效或丢失(无论原因如何),则需要返回Http状态401 我看到了
InvalidSessionStrategy
,但我没有找到在
SessionManagementFilter
上设置它的方法。 有人能告诉我如何实施我的计划或另一个满足要求的计划吗

,因为我使用的是AspectJ(我的意思是编译时编织,而不是Spring AOP),在构建
SessionManagementFilter
之后,通过设置我的自定义
InvalidSessionStrategy
可以很容易地破解
SessionManagementFilter
创建:

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

如果您没有使用AspectJ,请尝试添加
@Component
,并将此方面添加到您的上下文中,如果
SessionManagementFilter
是一个bean(因为Spring AOP应用程序只在Spring bean上运行)

我们遇到了完全相同的问题,我做了这个hack来解决它(是的,我知道,这是一个hack,因此名称…)。 我创建一个
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;
    }
}

使用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;
    }
}

您找到方法了吗?此解决方案有效,应该被称为Spring Security 4,2+的解决方案,可以在XML配置中使用元素会话管理和无效会话策略引用属性在安全http部分中完成。@pedorro,谢谢,这在Spring Security 5.1.4中也有效:-)