Vaadin 8.3.3 + управление сеансами Spring Security - PullRequest
0 голосов
/ 02 октября 2018

Я интегрировал свой проект Vaadin с Spring Security, поэтому у меня возникла проблема с управлением сессиями.В частности, с одновременным управлением сессиями.При этом пользователю разрешено входить в разные браузеры на одном ПК.Прилагается моя конфигурация и класс, который расширяет AbstractSecurityWebApplicationInitializer.

Вот мой класс конфигурации.

@EnableWebSecurity(debug = true)
@Configuration
@ComponentScan(basePackages = { "com.pnb" })
@EnableVaadin
@EnableVaadinNavigation
@PropertySource(value = "classpath:abo.properties")
public class ABOConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("authUserDetailsService")
    UserDetailsService userDetailsService;

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
//      HttpSecurity httpSec = http.regexMatcher("(?!.*HEARTBEAT)^.*\\/UI.*$")
        http
        .csrf().disable()
                .authorizeRequests()
                .antMatchers("/APP/**", "/VAADIN/**", "/HEARTBEAT/**", "/UIDL/**", "/resources/**", "/login",
                        "/login**", "/login/**", "/application")
                .permitAll()
                .anyRequest()
                .authenticated()
                .antMatchers("/**")
                .access("hasRole('ROLE')")
                .and()
                .requiresChannel()
                .anyRequest()
                .requiresSecure()
                .and()
                .exceptionHandling()
                .and()
                .formLogin()
                .loginPage("/login?auth")
                .defaultSuccessUrl("/application", true)
                .and()
                .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "PUT"))
                .logoutSuccessUrl("/login?auth")
                .clearAuthentication(true)
                .invalidateHttpSession(true)
                .deleteCookies("JSESSIONID")
                .and().headers().frameOptions().sameOrigin()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).sessionAuthenticationErrorUrl("/login/?auth")
                .sessionFixation().changeSessionId()
                .sessionAuthenticationStrategy(sessionAuthenticationStrategy())
                .invalidSessionUrl("/login/?auth")
                .maximumSessions(1).maxSessionsPreventsLogin(true).sessionRegistry(this.sessionRegistry())
                .expiredUrl("/login?auth")
                ;
    }


/*  @Bean
    @Qualifier("httpSessionEventPublisher")
    public HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }*/

    @Bean
    public Filter vaadinSessionRewriteFilter() {
        return new VaadinSessionRewriteFilter();
    }

    @Bean
    public SecurityContextHolder securityContextHolder(){
        SecurityContextHolder securityContextHolder = new SecurityContextHolder();
        return securityContextHolder;
    }

    @Bean
    protected SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }

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

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(encoder());
        return authProvider;
    }

    @Bean
    public AuthenticationTrustResolver getAuthenticationTrustResolver() {
        return new AuthenticationTrustResolverImpl();
    }

    @Bean
    public IWebClient getWebClient() {
        return WebClientFactory.getInstance();
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    public static SendEmailService sendEmailService(){
        return new SendEmailService();
    }

    @Bean
    public ConcurrentSessionControlAuthenticationStrategy concurrenSessionControlStrategy() {
        ConcurrentSessionControlAuthenticationStrategy concurrenSessionControlStrategy = new ConcurrentSessionControlAuthenticationStrategy(
                this.sessionRegistry());
        concurrenSessionControlStrategy.setMaximumSessions(1);
        concurrenSessionControlStrategy.setExceptionIfMaximumExceeded(true);
        return concurrenSessionControlStrategy;
    }

    @Bean
    public RegisterSessionAuthenticationStrategy registerSessionAuthenticationStrategy(){
        RegisterSessionAuthenticationStrategy registerSessionAuthenticationStrategy = new RegisterSessionAuthenticationStrategy(this.sessionRegistry());
        return registerSessionAuthenticationStrategy;
    }

    @Bean
    public SessionAuthenticationStrategy sessionAuthenticationStrategy(){
        List<SessionAuthenticationStrategy> strategies = new LinkedList<>();
        strategies.add(concurrenSessionControlStrategy());
        strategies.add(registerSessionAuthenticationStrategy());
        CompositeSessionAuthenticationStrategy compositeSessionAuthenticationStrategy = new CompositeSessionAuthenticationStrategy(strategies);
        return compositeSessionAuthenticationStrategy;
    }

}

Здесь мой класс, который расширяет AbstractSecurityWebApplicationInitializer.

@WebListener
@EnableVaadin
@Configuration
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer implements HttpSessionListener{

    private static final Map<String, HttpSession> sessions = new HashMap<String, HttpSession>();
    private final static Logger log = Logger.getLogger(MethodHandles.lookup().lookupClass());

    public SecurityWebApplicationInitializer() {
        super(ABOConfiguration.class, Config.class);
        log.debug("ENABLE HTTPSESSION EVENT PUBLISHER "+enableHttpSessionEventPublisher());
    }

    @Override
    protected boolean enableHttpSessionEventPublisher() {
        // this method changed everything for me
        return true;
    }


    public void sessionCreated(HttpSessionEvent event) {
        HttpSession session = event.getSession();
        sessions.put(session.getId(), session);
    }

    public void sessionDestroyed(HttpSessionEvent event) {
        sessions.remove(event.getSession().getId());
    }

    public static HttpSession find(String sessionId) {
        return sessions.get(sessionId);
    }

    public static Map<String, HttpSession> getSessions() {
        return sessions;
    }

}
...