首页 > 解决方案 > Spring Security:无法让真正的用户使用显示过期的 SessionRegistry 登录

问题描述

也许应该配置会话过期时间或错误在我的代码中?

我的控制器代码片段。即使已注销,它也会显示用户名。

@GetMapping("/")
  public String getProfilePage(Model model, Authentication authentication) {
    if (authentication == null) {
      return "redirect:/login";
    }
    UserDetailsImpl details = (UserDetailsImpl) authentication.getPrincipal();
    model.addAttribute("user", details.getUser());
    model.addAttribute("greeting", details.getUser().getGreeting());
    List<UserDetails> lu = sessionRegistry.getAllPrincipals()
        .stream()
        .filter(principal -> principal instanceof UserDetails)
        .map(UserDetails.class::cast)
        .collect(Collectors.toList());
    for (UserDetails l: lu){
      System.out.println(l.getUsername());
    }
    return "Profile";
  }

一个星期都解决不了这个问题。这里有一些答案,但它没有帮助解决我的问题。

标签: javaspringspring-bootspring-security

解决方案


这就是我的 SecurityConfig 类的样子:

public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Qualifier("dataSource")
  @Autowired
  private DataSource dataSource;

  @Autowired
  private PasswordEncoder passwordEncoder;

  @Autowired
  private UserDetailsService userDetailsServiceImpl;

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

    http
        .authorizeRequests()
        .antMatchers("/expired").permitAll()
        .antMatchers("/static/**").permitAll()
        .antMatchers("/users").hasAnyAuthority("ADMIN")
        .anyRequest().permitAll()
        .and()
        .formLogin().loginPage("/login")
        .usernameParameter("login")
        .passwordParameter("password")
        .failureUrl("/login?error").permitAll()
        .defaultSuccessUrl("/")
        .and()
        .rememberMe()
        .rememberMeParameter("remember-me")
        .tokenRepository(tokenRepository())
        .and()
        .logout()
        .deleteCookies("remember-me")
        .logoutUrl("/logout")
        .logoutSuccessUrl("/login")
        .permitAll();
    http.csrf().disable();
    http
        .sessionManagement()
        .maximumSessions(1)
//        .maxSessionsPreventsLogin(false)
        .sessionRegistry(sessionRegistryImpl());
  }

  @Bean
  public SessionRegistryImpl sessionRegistryImpl() {
    return new SessionRegistryImpl();
  }

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

  @Bean
  public PersistentTokenRepository tokenRepository() {
    JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
    tokenRepository.setDataSource(dataSource);
    return tokenRepository;
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsServiceImpl).passwordEncoder(passwordEncoder);
  }
}

并添加了 AppInitializer:

@Configuration
public class AppInitializer implements WebApplicationInitializer {

  @Override
  public void onStartup(ServletContext servletContext) throws ServletException {
    servletContext.addListener(HttpSessionEventPublisher.class);
  }
}

推荐阅读