Я добавляю 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
для сохранения информации о сеансе?
В угловую сторону я использую 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
или другим способом для этого результата, дайте мне знать. Спасибо!