【问题标题】:How to set a custom invalid session strategy in Spring Security如何在 Spring Security 中设置自定义无效会话策略
【发布时间】:2014-09-12 13:23:04
【问题描述】:

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

}

要求返回 Http 状态 401 以防会话 cookie 无效或丢失(无论原因) 我看到了InvalidSessionStrategy,但我找不到在SessionManagementFilter 上设置它的方法。 有人可以指导我如何实施我的计划或另一个可以满足要求的计划

【问题讨论】:

  • 你找到方法了吗?

标签: spring-security


【解决方案1】:

使用 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 配置中使用元素 session-management 和 invalid-session-strategy-ref 属性在安全 http 部分中完成。
  • @pedorro,谢谢,这也适用于 Spring security 5.1.4 :-)
【解决方案2】:

我们遇到了完全相同的问题,我做了这个 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;
    }
}

【讨论】:

  • 此解决方案有效,应作为解决方案提及
【解决方案3】:

由于我使用的是 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 并将此 Aspect 添加到您的上下文中,如果 SessionManagementFilter 是一个 bean,它可能会起作用(因为 Spring-AOP 仅适用于 spring bean)

【讨论】:

    猜你喜欢
    • 2011-03-28
    • 2015-10-16
    • 2015-08-08
    • 2020-05-09
    • 2016-08-16
    • 2019-05-08
    • 1970-01-01
    • 2013-04-27
    相关资源
    最近更新 更多