【问题标题】:How to exclude inactive users? (Spring Security)如何排除非活跃用户? (春季安全)
【发布时间】:2020-10-24 04:48:11
【问题描述】:

我得到了所有活跃用户,但是当用户退出时,它仍然被列为活跃用户。如何防止用户在退出后被列为活动用户?

我无法在文档中找到解决方案。

https://github.com/romanych2021/TestSession

谢谢。

ActiveUserServiceImpl.java

    @Service
    public class ActiveUserServiceImpl implements ActiveUserService{


        @Autowired
        SessionRegistry sessionRegistry;


        public List<String > getAllActiveUser(){

            List<Object> principals = sessionRegistry.getAllPrincipals();
            User[] users = (User[]) principals.toArray(new User[0]);

            return Arrays.stream(users)
                    .filter(user -> !sessionRegistry.getAllSessions(user, false)
                    .isEmpty()).map(User::getUsername).collect(Collectors.toList());

        }

    }

SecurityConfig.java

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {


        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()

                    .mvcMatchers("/").permitAll()
                    .mvcMatchers("/login").anonymous()
                    .mvcMatchers("/user", "/allUser").hasAnyRole("ADMIN", "USER")
                    .anyRequest().authenticated()

                    .and()
                    .formLogin()
                    .loginPage("/login")
                    .loginProcessingUrl("/login")

                    .defaultSuccessUrl("/")

                    .and().csrf().disable()

                    .logout()
                    .permitAll()
                    .logoutUrl("/logout")
                    .logoutSuccessUrl("/")

                    .invalidateHttpSession(true)
                    .deleteCookies("JSESSIONID")

                    .and().sessionManagement()
                    .maximumSessions(1)
                    .expiredUrl("/login")
                    .sessionRegistry(sessionRegistry);

        }


    }

HTML

    <form method="post" action="/logout">
        <button type="submit">Exit</button>
    </form>

【问题讨论】:

标签: spring spring-mvc spring-security


【解决方案1】:

将您的活动用户映射保留在 hashMap 中,并在当天注销时从该映射中删除被删除的用户。在 value unbound 事件中,您可以排除非活动用户。

@Getter
@Setter
public class ActiveUserStore {

    public HashMap<String, ActorUser> userDetails;

    public ActiveUserStore() {

        userDetails = new HashMap<>();
    }
}


@Getter
@Setter
public class LoggedUser implements HttpSessionBindingListener {


    private ActorUser sessionUser;
    private ActiveUserStore activeUserStore;

    public LoggedUser(ActorUser sessionUser, ActiveUserStore activeUserStore) {

        this.activeUserStore = activeUserStore;
        this.sessionUser = sessionUser;
    }


    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        HashMap<String, ActorUser> userDetails = activeUserStore.getUserDetails();
        LoggedUser loggedUser = (LoggedUser) event.getValue();

        if (isNotNull(userDetails) && !userDetails.containsKey(loggedUser.getSessionUser().getUsername())) {
            userDetails.put(loggedUser.getSessionUser().getUsername(), loggedUser.getSessionUser());
        }

    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        LoggedUser loggedUser = (LoggedUser) event.getValue();
        HashMap<String, ActorUser> userDetails = activeUserStore.getUserDetails();

        if (isNotNull(userDetails) && isNotNull(loggedUser.getSessionUser()) &&
                userDetails.containsKey(loggedUser.getSessionUser().getUsername())) {
            userDetails.remove(loggedUser.getSessionUser().getUsername());
        }

    }

【讨论】:

【解决方案2】:

为了解决这个问题,我只需要创建一个类。

    package com.testsession.service;

    import org.springframework.security.web.session.HttpSessionEventPublisher;
    import org.springframework.web.WebApplicationInitializer;

    import javax.servlet.ServletContext;

    public class MyWebAppInitializer implements WebApplicationInitializer {

        @Override
        public void onStartup(ServletContext container) {
            container.addListener(new HttpSessionEventPublisher());
        }
    }

【讨论】:

    猜你喜欢
    • 2014-10-08
    • 2016-11-12
    • 2013-12-22
    • 1970-01-01
    • 2014-04-08
    • 2014-02-02
    • 2012-12-13
    相关资源
    最近更新 更多