【问题标题】:Spring boot sessionRegistry returns empty list of principalsSpring Boot sessionRegistry 返回空的委托人列表
【发布时间】:2018-01-02 23:51:21
【问题描述】:

我在我的 Spring Boot 应用程序中使用 Spring Security 来提供用户功能。我花了一些时间安静地寻找问题的答案,但只为使用基于 xml 的配置的人找到了解决方案。

我的设置与此非常相似:http://www.baeldung.com/spring-security-track-logged-in-users(底部的替代方法)。

这是我的安全配置:

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

    http.formLogin().defaultSuccessUrl("/home.html", true)
    //.and().exceptionHandling().accessDeniedPage("/home")
    .and().authorizeRequests().antMatchers("/editor").hasAnyAuthority("SUPERUSER")
    .and().authorizeRequests().antMatchers("/editor").hasAnyAuthority("ADMIN")
    .and().authorizeRequests().antMatchers("/").permitAll().anyRequest().authenticated()
    .and().formLogin().loginPage("/login").permitAll()
    .and().authorizeRequests().antMatchers("/static/**").permitAll()
    .and().logout().permitAll().logoutSuccessUrl("/login").logoutUrl("/logout").deleteCookies("JSESSIONID")
    .and().csrf().disable();

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


}

这是我调用 sessionRegistry 的地方:

public List<String> getAllLoggedUsernames() {

    final List<Object> allPrincipals = sessionRegistry.getAllPrincipals();
    // System.out.println("All Principals: " + sessionRegistry.getAllPrincipals());
    List<String> allUsernames = new ArrayList<String>();
    System.out.println(allUsernames.size());
    for (final Object principal : allPrincipals) {

        if (principal instanceof SecUserDetails) {
            final SecUserDetails user = (SecUserDetails) principal;

            //Make sure the session is not expired --------------------------------------------------▼ 
            List<SessionInformation> activeUserSessions = sessionRegistry.getAllSessions(principal, false);
            if (!activeUserSessions.isEmpty()) {
                allUsernames.add(user.getUsername());
                System.out.println(user.getUsername());
            }

        }
    }

    return allUsernames;
}

现在,当我尝试获取当前登录的用户时,我得到了正确的结果:

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    String username = auth.getName();

我的 sessionRegistry 通过以下方式定义为 Bean:

@Bean
public SessionRegistry sessionRegistry() {
    return new SessionRegistryImpl();

}

可以说,我通过类似这样的服务从控制器调用 getAllLoggedUsernames()

@Autowired
private SecUserDetailService service;

稍后在 @RequestMapping 函数中:

service.getAllLoggedUsernames();

无论有多少用户实际登录,那里收到的列表总是空的。

现在我从这里提出的其他问题的猜测是我的应用程序以某种方式加载了两次,或者我的 bean 设置被搞砸了。我有点认为@Autowired 不起作用,因为我认为服务需要某种上下文信息?

虽然我对依赖注入真的很陌生,所以很难让一切都正确。

提前感谢您的帮助!

编辑 - 次要说明

【问题讨论】:

  • 你的sesionRegistry()方法是做什么的...
  • 恐怕我不明白你的意思,因为我的代码中没有一个名为 sessionRegistry() 的方法。你的意思是getPrincipals() 方法吗?
  • 那么sessionRegistry() 方法是从哪里来的,你在配置中使用它。
  • 哦,对不起!它只是像这样返回 sessionRegistryImpl 对象:@Bean public SessionRegistry sessionRegistry() { return new SessionRegistryImpl(); }
  • 你还需要 HttpSessionEventPublisher 作为 bean。

标签: java spring spring-boot javabeans


【解决方案1】:

已解决:出现类型错误,getAllLoggedUsers() 方法中的 if 语句始终解析为 false,因为 Object 不是我自己的 UserDetails 类的实例,而是 org.springframework.security.core.userdetails.User 的实例!

【讨论】:

猜你喜欢
  • 2021-05-16
  • 2022-06-15
  • 2021-06-27
  • 2020-06-15
  • 2019-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多