Spring Security并发会话控制

时间:2019-01-27 10:14:12

标签: spring spring-boot spring-mvc spring-security

我试图将用户会话一次从任何位置限制为一个会话。但这是行不通的。当我尝试在两个导航器上以同一用户访问该应用程序时,我具有访问权限。 我注意到,当用户连接到两台不同计算机上的应用程序以开始打印两个不同的报告时,就会出现一个打印出来的图像,而不是另一个。 感谢帮助。

我的安全性配置类:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    /*@Autowired
    private DataSource dataSource;*/

    private AccessDeniedHandler accessDeniedHandler;
    private AuthenticationSuccessHandler authenticationSuccessHandler;
    private AuthenticationFailureHandler authenticationFailureHandler;
    private UserDetailsService userDetailsService;

    @Autowired
    public SecurityConfiguration( 
            @Qualifier("customAccessDeneiedHandler")AccessDeniedHandler accessDeniedHandler,
            @Qualifier("customSuccessHandler")AuthenticationSuccessHandler authenticationSuccessHandler,
            @Qualifier("customAuthenticationFailureHandler")AuthenticationFailureHandler authenticationFailureHandler,
            @Qualifier("customUserDetailsService")UserDetailsService userDetailsService) {
        this.accessDeniedHandler = accessDeniedHandler;
        this.authenticationSuccessHandler = authenticationSuccessHandler;
        this.authenticationFailureHandler = authenticationFailureHandler;
        this.userDetailsService = userDetailsService;
    }


    /* (non-Javadoc)
     * @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder)
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // TODO Auto-generated method stub
        //super.configure(auth);

        auth.userDetailsService(userDetailsService)   //auth.userDetailsService(utilisateurDetailsService)
            .passwordEncoder(passwordEncoder());
    }

    //Authorization
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
                //.antMatchers("/").permitAll()
                .antMatchers("/ajouterassure", "/ajouterattributaire", "/ajouterbeneficiaire", "/ajouterpiecejustificative",
                             "/creerbordereauemission", "/creerbehorscoordination", "/creerbordereaupaie", "/ajouteravance", 
                             "/creerbeavanceannuelle")
                            .hasAnyRole("DGA", "DGAA", "DR", "DRA", "CC", "CCA", "CI", "AS", "GUICHET", "CE", "CAP", "ADMIN") //.hasRole("ADMIN")

                .antMatchers("/ajoutercentre", "/ajouteretablissementpaie", "/ajoutertypepj", "/ajoutertypedette",
                             "/ajoutersexe", "/ajoutersituationbeneficiaire", "/ajoutercategoriebeneficiaire", 
                             "/ajoutercategorieattributaire", "/ajouterrevalorisation").hasAnyRole("DGA", "ADMIN")  //hasAnyRole("CAP", "ADMIN")
                .antMatchers("/payerdecompte").hasAnyRole("CAISSIER", "ADMIN")
                .antMatchers("/ajouterutilisateur").hasAnyRole("CI", "ADMIN")
                .anyRequest().authenticated()
                .and()
                //.httpBasic()
            .formLogin()
                .loginPage("/login")
                //.loginProcessingUrl("/login")
                .usernameParameter("identifiant")
                .passwordParameter("mot_de_passe")
                .successHandler(authenticationSuccessHandler)
                .failureHandler(authenticationFailureHandler)
                //.defaultSuccessUrl("/")
                .permitAll()
                .and()
            .logout().permitAll()
                    .and()
                .sessionManagement()            //Session controle concurence access
                    .maximumSessions(1)
                    .expiredUrl("/login?expired")
                    .sessionRegistry(sessionRegistry);

        http.exceptionHandling().accessDeniedHandler(accessDeniedHandler);

        //Session controle concurence access
        //http.sessionManagement().maximumSessions(1);
    }

    /* (non-Javadoc)
     * @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.WebSecurity)
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**", "/resources/templates/errors/**", "/static/**", "/css/**", "/images/**", "/var/signatures/**");
        //web.ignoring().antMatchers("/static/**");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }



 @Bean(name = "sessionRegistry")
 public SessionRegistry sessionRegistry() {
     return new SessionRegistryImpl();
 }

    @Autowired
    @Lazy
    private SessionRegistry sessionRegistry;
}

2 个答案:

答案 0 :(得分:0)

[以防万一有人发现它有用。]

始终在自定义UserDetails类中添加哈希码和equals方法,并在spring安全配置类中添加以下配置,以使并发会话正常工作。

protected void configure(HttpSecurity http) throws Exception 
{
    http.sessionManagement().maximumSessions(1);
}

@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() 
{
    return new HttpSessionEventPublisher();
}

答案 1 :(得分:0)

您只需在.maxSessionsPreventsLogin(true)之后添加maximumSessions(1),它就会从util会话在这里到期的其他地方停止登录。因此,您的configure方法应如下所示:-

protected void configure(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .authorizeRequests()
            //.antMatchers("/").permitAll()
            .antMatchers("/ajouterassure", "/ajouterattributaire", "/ajouterbeneficiaire", "/ajouterpiecejustificative",
                         "/creerbordereauemission", "/creerbehorscoordination", "/creerbordereaupaie", "/ajouteravance", 
                         "/creerbeavanceannuelle")
                        .hasAnyRole("DGA", "DGAA", "DR", "DRA", "CC", "CCA", "CI", "AS", "GUICHET", "CE", "CAP", "ADMIN") //.hasRole("ADMIN")

            .antMatchers("/ajoutercentre", "/ajouteretablissementpaie", "/ajoutertypepj", "/ajoutertypedette",
                         "/ajoutersexe", "/ajoutersituationbeneficiaire", "/ajoutercategoriebeneficiaire", 
                         "/ajoutercategorieattributaire", "/ajouterrevalorisation").hasAnyRole("DGA", "ADMIN")  //hasAnyRole("CAP", "ADMIN")
            .antMatchers("/payerdecompte").hasAnyRole("CAISSIER", "ADMIN")
            .antMatchers("/ajouterutilisateur").hasAnyRole("CI", "ADMIN")
            .anyRequest().authenticated()
            .and()
            //.httpBasic()
        .formLogin()
            .loginPage("/login")
            //.loginProcessingUrl("/login")
            .usernameParameter("identifiant")
            .passwordParameter("mot_de_passe")
            .successHandler(authenticationSuccessHandler)
            .failureHandler(authenticationFailureHandler)
            //.defaultSuccessUrl("/")
            .permitAll()
            .and()
        .logout().permitAll()
                .and()
            .sessionManagement()            //Session controle concurence access
                .maximumSessions(1)
                .expiredUrl("/login?expired")
                .sessionRegistry(sessionRegistry);

    http.exceptionHandling().accessDeniedHandler(accessDeniedHandler);

    //Session controle concurence access
    //http.sessionManagement().maximumSessions(1);
}