Я добавляю 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 или другим способом для этого результата, дайте мне знать. Благодарю вас!
Увеличьте уровень журнала, может быть полезно найти причину этого. Кстати: класс LoggedInChecker, на мой взгляд, должен иметь область сеанса.




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