SessionRegistry返回经过身份验证的用户的空列表

时间:2017-01-07 14:49:33

标签: spring spring-mvc spring-security

我有一个事件监听器,当它收到用户更改密码的事件时会使会话无效。这是代码:

@Component
public class UserListener {

    private static Logger logger = LoggerFactory.getLogger(UserListener.class);

    @Autowired
    private SessionRegistry sessionRegistry;

    @EventListener
    public void handleChangePasswordEvent(ChangePasswordEvent event) {
        logger.info("handleChangePasswordEvent for : " + event.getUsername());
        List<Object> loggedUsers = sessionRegistry.getAllPrincipals();
        logger.info("loggedUsers : " + loggedUsers.size());
        for (Object principal : loggedUsers) {
            if (principal instanceof User) {
                final User loggedUser = (User) principal;
                logger.info("loggedUser : " + loggedUser.getUsername());
                if (event.getUsername().equals(loggedUser.getUsername())) {
                    List<SessionInformation> sessionsInfo = sessionRegistry.getAllSessions(principal, false);
                    if (null != sessionsInfo && sessionsInfo.size() > 0) {
                        for (SessionInformation sessionInformation : sessionsInfo) {
                            logger.info("Exprire now :" + sessionInformation.getSessionId());
                            sessionInformation.expireNow();
                            sessionRegistry.removeSessionInformation(sessionInformation.getSessionId());
                            // User is not forced to re-logging
                        }
                    }
                }
            }
        }
    }
}

监听器工作正常,问题是返回sessionRegistry的经过身份验证的用户列表为空。

我已经尝试了所有我遇到的同样问题的解决方案,但他们没有为我工作。

这里我放了Spring Security的所有配置。

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
@EnableWebSecurity
@ComponentScan(value = { "security" })
public class SecurityConfig extends GlobalAuthenticationConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private CustomLogoutHandler logoutHandler;


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

    @Autowired
    protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .authenticationEventPublisher(authenticationEventPublisher())
            .userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder());
    }

    @Bean
    public DefaultAuthenticationEventPublisher authenticationEventPublisher() {
        return new DefaultAuthenticationEventPublisher();
    }


    /**
     * Security Configuration for Admin zone
     */
    @Configuration
    @Order(1)
    public class AdminConfiguration extends WebSecurityConfigurerAdapter {

        @Autowired
        private AuthenticationSuccessHandler successHandler;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                .antMatchers("/admin/**")
                .hasAuthority(AuthorityEnum.ROLE_ADMIN.name())
                .and()
                .formLogin()
                    .loginPage("/admin/login")
                    .usernameParameter("username")
                    .passwordParameter("password")
                    .successHandler(successHandler)
                    .permitAll()
                .and()
                .logout()
                    .addLogoutHandler(logoutHandler)
                    .logoutRequestMatcher(new AntPathRequestMatcher("/admin/logout"))
                    .logoutSuccessUrl("/admin/login?logout")
                    .deleteCookies("JSESSIONID")
                    .invalidateHttpSession(true)
                .and()
                .exceptionHandling().accessDeniedPage("/403")
                .and()
                .csrf()
                .disable();
        }
    }


    /**
     * Security Configuration for Frontend zone
     */
    @Configuration
    @Order(2)
    public class FrontendConfiguration extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                .antMatchers("/*.*")
                .permitAll()
                .and()
                .formLogin()
                    .loginPage("/login")
                    .usernameParameter("username")
                    .passwordParameter("password")
                    .permitAll()
                .and()
                .logout()
                    .addLogoutHandler(logoutHandler)
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .logoutSuccessUrl("/login?logout")
                    .deleteCookies("JSESSIONID")
                    .invalidateHttpSession(true)
                .and()
                .exceptionHandling().accessDeniedPage("/403")
                .and()
                .csrf();
        }
    }

    @Configuration
    @Order(3)
    public class GlobalWebConfiguration extends WebSecurityConfigurerAdapter {

        private SessionRegistry sessionRegistry;

        @Autowired
        private MessageSource messageSource;

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.sessionManagement()
                    .sessionAuthenticationStrategy(compositeSessionAuthenticationStrategy())
                    .sessionFixation()
                    .changeSessionId()
                    .maximumSessions(1)
                    .maxSessionsPreventsLogin(true)
                    .expiredUrl("/login?expired")
                    .sessionRegistry(sessionRegistry())
                    .and()
                    .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                    .invalidSessionUrl("/");

            // Here we protect site from:
            // 1. X-Content-Type-Options
            http.headers().contentTypeOptions();
            // 2. Web Browser XSS Protection
            http.headers().xssProtection();
            http.headers().cacheControl();
            http.headers().httpStrictTransportSecurity();
            // 3. X-Frame-Options
            http.headers().frameOptions();

        }

        @Bean
        public SessionRegistry sessionRegistry() {
            if (sessionRegistry == null) {
                sessionRegistry = new SessionRegistryImpl();
            }
            return sessionRegistry;
        }

        @Bean
        @Order(1)
        public ConcurrentSessionControlAuthenticationStrategy concurrentSessionControlAuthenticationStrategy() {
            ConcurrentSessionControlAuthenticationStrategy strategy = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
            strategy.setExceptionIfMaximumExceeded(true);
            strategy.setMessageSource(messageSource);
            return strategy;
        }

        @Bean
        @Order(2)
        public SessionFixationProtectionStrategy sessionFixationProtectionStrategy(){
            return new SessionFixationProtectionStrategy();
        }

        @Bean
        @Order(3)
        public RegisterSessionAuthenticationStrategy registerSessionAuthenticationStrategy(){
            RegisterSessionAuthenticationStrategy registerSessionAuthenticationStrategy = new RegisterSessionAuthenticationStrategy(sessionRegistry());
            return registerSessionAuthenticationStrategy;
        }

        @Bean
        public CompositeSessionAuthenticationStrategy compositeSessionAuthenticationStrategy(){
            List<SessionAuthenticationStrategy> sessionAuthenticationStrategies = new ArrayList<>();
            sessionAuthenticationStrategies.add(concurrentSessionControlAuthenticationStrategy());
            sessionAuthenticationStrategies.add(sessionFixationProtectionStrategy());
            sessionAuthenticationStrategies.add(registerSessionAuthenticationStrategy());
            CompositeSessionAuthenticationStrategy compositeSessionAuthenticationStrategy = new CompositeSessionAuthenticationStrategy(sessionAuthenticationStrategies);
            return compositeSessionAuthenticationStrategy;
        }

    }
}

我有一个用于管理区域的WebSecurityConfigurerAdapter,它有自己的登录页面,另一个用于普通用户。

最后是 GlobalWebConfiguration ,为两个区域(管理员和用户)配置会话管理器。

希望有人可以帮助我

0 个答案:

没有答案
相关问题