2016-11-18 4 views
0

Я делаю основной проект Tic Tac toe с весной, весной и спящим. Приложение может сохранять игру для каждого зарегистрированного пользователя в базе данных и позволяет загружать ее, когда захочет. Это не проблема, но она появляется, когда дело касается многопоточности. Когда я запускаю одно приложение в одном окне браузера, все работает хорошо. Но когда я открываю другое окно, два игрока играют в одну и ту же игру.Ошибка Spring Security с несколькими зарегистрированными пользователями

Я знаю, что это может быть вызвано синонимами, созданными весной, но я уверен, что это не так. Для проверки текущего пользователя, я сделал метод, чтобы получить его от SecurityContextHolder

private User getUserFromSpringContext() { 
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
    String name = authentication.getName(); 
    System.out.println("Currently logged users = " + name); 
    return userService.findUserByUsername(name); 
} 

Когда несколько пользователей в, то печатает название Метод предписывает только одного из них. Понятия не имею почему. Вот некоторые важные строки кода мои настройки безопасности и UserDetails классы:

конфигурации безопасности:

@Autowired 
UserDetailsService userDetailsService; 

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

@Bean 
public DaoAuthenticationProvider authenticationProvider() { 
    DaoAuthenticationProvider auth = new DaoAuthenticationProvider(); 
    auth.setUserDetailsService(userDetailsService); 
    return auth; 
} 

Пользовательские пользователей Подробнее Сервис

@Autowired 
private UserService userService; 

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
    User user = userService.findUserByUsername(username); 
    if (user == null) { 
     throw new UsernameNotFoundException("Username not found"); 
    } 
    return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), true, true, true, true, getAuthoriries(user)); 
} 

public void setUserService(UserService userService) { 
    this.userService = userService; 
} 

private List<GrantedAuthority> getAuthoriries(User user) { 
    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 
    authorities.add(new SimpleGrantedAuthority(user.getRole().getRole())); 
    return authorities; 
} 

ли знает кто причину этой проблемы?

Во время тестирования у меня возникла другая проблема. Когда я нажимаю «Выход», все пользователи выходят из системы. Я размещаю здесь остальную часть моей конфигурации безопасности Spring.

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http.authorizeRequests() 
      .antMatchers("/start", "/", "/login", "/registry","/success","/new").permitAll() 
      .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')") 
      .antMatchers("/**").access("hasAnyRole('ROLE_USER','ROLE_ADMIN')") 
      .and().formLogin().loginPage("/login").defaultSuccessUrl("/user") 
      .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")) 
      .and().csrf() 
      .and().exceptionHandling().accessDeniedPage("/access_denied"); 
} 

В чем может быть проблема?

+0

Предполагая, что он работает так, как я думаю, он действительно утверждал (однако), что при входе пользователя в систему их записи создаются в вашей базе данных? возможно, это работает только для самого первого пользователя? –

+0

Я отредактировал сообщение, потому что нашел другую проблему. –

+0

Определить открытие нового окна? Если вы нажимаете CTRL + T или CTRL + N из существующего браузера, который не является новым браузером. Состояние сеанса, кеш и файлы cookie будут скопированы. На самом деле вы не играете с несколькими игроками, а с одним пользователем в нескольких окнах браузера. Я бы сказал, что это работает так, как нужно, и вы просто проверяете его не так. –

ответ

3

SecurityContextHolder дает вам доступ к контексту безопасности, связанной с текущего потока, таким образом, только пользователь ток - тот, чей запрос вызвал призыв к getAuthentication(), поэтому он ведет себя именно так, как надо.

Если вы хотите, чтобы все активные сеансы (т. Е. Все зарегистрированные пользователи), вы должны ввести SessionRegistry и позвонить по нему sessionRegistry.getAllPrincipals().

Подробнее уже показаны here.

Смежные вопросы