【问题标题】:spring security: disable multiple sessions on the same user not workingspring security:禁用同一用户的多个会话不起作用
【发布时间】:2019-12-06 01:06:56
【问题描述】:

HttpSecurity 对象配置如下:

http.authorizeRequests().antMatchers("/login","/loginPage","/static/login.html","/","/index","/static/authenticationErr.html","/static/duplicatedUserErr.html").permitAll()
    .and()
    .httpBasic()
    .authenticationEntryPoint(customAuthenticationEntryPoint)
    .and()
    .addFilterAt(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
    .csrf().disable()
    .authorizeRequests()
    .anyRequest().authenticated()
    .and()
    .formLogin()
    .loginProcessingUrl("/login")
    .loginPage("/loginPage")
    .permitAll()
    .and()
    .logout()
    .logoutUrl("/logout")
    .logoutSuccessHandler(customLogoutHandler)
    .permitAll()

    .and()
    .sessionManagement() // not working??
    .maximumSessions(1)
    .maxSessionsPreventsLogin(true)
    .expiredUrl("/static/duplicatedUserErr.html")
    ;

这是我尝试过的:通过遵循https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#concurrent-sessions 的 spring 安全参考和源代码跟踪,我发现确定这是否是重复登录会话的关键是这部分代码是用方法 onAuthentication 编写的班级ConcurrentSessionControlAuthenticationStrategy:

final List<SessionInformation> sessions = sessionRegistry.getAllSessions(
            authentication.getPrincipal(), false);

然后根据此列表的大小,与HttpSecurity 配置中定义的最大会话数限制进行比较,以检查这是否是重复用户。经过调试,我知道每次用户尝试登录时,都会调用这行代码,但是无论在我的浏览器中尝试登录多少次,sessions对象总是为空,原来principals字段SessionRegistryImpl 中定义的地图自创建以来一直是空地图,并且永远不会被新元素填充。

这是我的配置的其他细节:

AuthenticationProvider:org.springframework.security.authentication.dao.DaoAuthenticationProvider

用户详细信息服务: CustomUserDetailsS​​ervice 实现UserDetailsService

用户详情: org.springframework.security.core.userdetails.User

身份验证处理过滤器: CustomAuthenticationFilter 扩展 AbstractAuthenticationProcessingFilter

更新

@Bean
public CustomAuthenticationFilter customAuthenticationFilter() throws Exception {
    CustomAuthenticationFilter filter = new CustomAuthenticationFilter("/login");
    filter.setAuthenticationManager(this.authenticationManagerBean());
    filter.setAuthenticationFailureHandler(failureHandler);
    filter.setAuthenticationSuccessHandler(successHandler);

    filter.setSessionAuthenticationStrategy(sessionControlAuthenticationStrategy());
    return filter;
}

谁能告诉我这个?

【问题讨论】:

    标签: spring-boot spring-security


    【解决方案1】:

    最后我想通了,你必须按照这个参考https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#concurrent-sessions创建bean,你必须手动将CompositeSessionAuthenticationStrategy bean设置为CustomAuthenticationFilter,然后在你的ConcurrentSessionControlAuthenticationStrategy bean中,设置ExceptionIfMaximumExceeded为true 因此,当创建同一用户的重复视图时,它将抛出 SessionAuthenticationException。 我上面描述的代码是这样的:

    @Bean
    public CustomAuthenticationFilter customAuthenticationFilter() throws Exception {
        CustomAuthenticationFilter filter = new CustomAuthenticationFilter("/login");
        filter.setAuthenticationManager(this.authenticationManagerBean());
        filter.setAuthenticationFailureHandler(failureHandler);
        filter.setAuthenticationSuccessHandler(successHandler);
        //If don't set it here, spring will inject a compositeSessionAuthenticationStrategy bean automatically, but looks like it didn't work as expected for me
        filter.setSessionAuthenticationStrategy(compositeSessionAuthenticationStrategy());
        return filter;
    }
    @Bean
        public ConcurrentSessionControlAuthenticationStrategy sessionControlAuthenticationStrategy() {
            ConcurrentSessionControlAuthenticationStrategy csas = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
            csas.setExceptionIfMaximumExceeded(true);
            return csas;
        }
    

    【讨论】:

      猜你喜欢
      • 2015-12-26
      • 2018-12-12
      • 2022-10-12
      • 2019-11-21
      • 2021-04-18
      • 1970-01-01
      • 2016-06-30
      • 1970-01-01
      • 2020-03-30
      相关资源
      最近更新 更多