Spring Security не распознает, кто вошел в систему

Я добавляю Spring Security в свое приложение Spring Boot, но после этого сервер процесса аутентификации не распознает того же пользователя в следующем запросе. Я использую Angular 5 для пользовательского интерфейса, и, возможно, эта проблема на стороне пользовательского интерфейса может быть запрошена без включения файлов cookie. Помогите мне, пожалуйста, поймите, почему Spring Security не распознает пользователя, который уже вошел в систему.

В веб-конфигурации:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/rest/user/login").permitAll();
    http.csrf().disable()
            .authenticationProvider(authenticationProvider())
            .exceptionHandling()
            .authenticationEntryPoint(unauthorizedHandler)
            .and()
            .formLogin()
            .permitAll()
            .loginProcessingUrl("/rest/user/login")
            .usernameParameter("username")
            .passwordParameter("password")
            .successHandler(logInSuccessHandler)
            .failureHandler(authFailureHandler)
            .and()
            .logout().permitAll()
            .logoutRequestMatcher(new AntPathRequestMatcher("/rest/user/logout", "POST"))
            .logoutSuccessHandler(logoutHandler)
            .and()
            .sessionManagement()
            .maximumSessions(1);

    http.authorizeRequests().anyRequest().authenticated();
}

Активирован менеджер сессий .sessionManagement().maximumSessions(1);

И аутентификация завершилась успешно, моя реализация UserDetailsService правильно вернула объект User по логину и паролю. Но следующий запрос к этому контроллеру:

@GetMapping("/rest/list")
public RestList list() {
    ...
}

Перенаправить на:

@Component
public class UnauthorizedHandler implements AuthenticationEntryPoint {
    @Override
    public void commence(
            HttpServletRequest request,
            HttpServletResponse response,
            AuthenticationException authException) throws IOException {

        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
    }
}

У меня есть авторизованный чекер:

@Component
public class LoggedInChecker {
    public User getLoggedInUser() {
        User user = null;

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null) {
            Object principal = authentication.getPrincipal();
            // principal can be "anonymousUser" (String)
            if (principal instanceof UserDetailsImpl) {
                UserDetailsImpl userDetails = (UserDetailsImpl) principal;
                user = userDetails.getUser();
            }
        }
        return user;
    }
}

Пользуюсь этой чекой в ​​UserService

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private LoggedInChecker loggedInChecker;

    @Override
    public User getUserByUsername(String username) {
        return userRepository.findByUsername(username);
    }

    @Override
    public List<String> getPermissions(String username) {
        User user = userRepository.findByUsername(username);
        return nonNull(user) ? user.getRoles().stream().map(Role::getRole).collect(toList()) : Lists.newArrayList();
    }

    @Override
    public User getCurrentUser() {
        return loggedInChecker.getLoggedInUser();
    }

    @Override
    public Boolean isCurrentUserLoggedIn() {
        // This place must call but nothing happening
        return nonNull(loggedInChecker.getLoggedInUser());
    }
}

Я думал, что Spring автоматически вызывает мой UserSevice для проверки авторизации. Но как указать HttpSecurity для сохранения информации о сеансе?

На стороне Angular я использую HttpClient:

@Injectable()
export class CoreApi {
  private baseUrl = 'http://localhost:8080/rest/';

  constructor(public http: HttpClient) {
  }

  public get(url: string = ''): Observable<any> {
    return this.http.get(this.getUrl(url));
  }
}

Возможно, вы знаете, как указать Spring Security для проверки аутентификации с помощью LoggedInChecker или другим способом для этого результата, дайте мне знать. Благодарю вас!

Из вашего приложения Angular, когда вы отправляете запрос, каждый раз, когда вы перенаправляетесь на URL-адрес аутентификации и после успешного перенаправления запроса аутентификации на требуемый URL-адрес? Или ваше приложение Spring проходит через запрос без перенаправления на адрес аутентификации? По моему опыту, вы должны сделать немного магии в Angular, чтобы быть уверенным, что он будет отправлять cookie аутентификации в каждом запросе.

Aleksandrs Rudzitis 08.05.2018 08:15

Увеличьте уровень журнала, может быть полезно найти причину этого. Кстати: класс LoggedInChecker, на мой взгляд, должен иметь область сеанса.

Kamil W 08.05.2018 08:17
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
326
0

Другие вопросы по теме