Я получаю сообщение об ошибке "Servlet.service () для сервлета [dispatcherServlet] в контексте с путем [] вызвала исключение [отправка обработчика не удалась; вложенное исключение java .lang.StackOverflowError] с root причиной java .lang.StackOverflowError: null "
Я пытаюсь отладить свой код, но не могу понять причину этой ошибки.
Я получаю эту ошибку в своем классе AuthService в строке ;
Authentication authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
Вот мой класс AuthService;
@Service
public class AuthService {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtProvider jwtProvider;
.........................................
public String login(LoginRequest loginRequest){
Authentication authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(),
loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authenticate);
return jwtProvider.generateToken(authenticate);
}
}
Файл SecurityConfig:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean(BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable().authorizeRequests()
.antMatchers("/api/auth/**")
.permitAll()
.anyRequest()
.authenticated();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
Класс AuthController:
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthService authService;
@PostMapping("/login")
public String login(@RequestBody LoginRequest loginRequest){
return authService.login(loginRequest);
}
}
LoginRequest dto:
public class LoginRequest {
private String username;
private String password;
...getters and setters...
}
Модель пользователя:
@Entity
@Table
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String userName;
@Column
private String password;
@Column
private String email;
...getters and setters...
}
Интерфейс UserRepository:
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUserName(String username);
}
JwtProvider:
@Service
public class JwtProvider {
private Key key;
@PostConstruct
public void init(){
key = Keys.secretKeyFor(SignatureAlgorithm.HS512);
}
public String generateToken(Authentication authentication){
User principal = (User) authentication.getPrincipal();
return Jwts.builder()
.setSubject(principal.getUsername())
.signWith(key)
.compact();
}
}
UserDetailsServiceImpl класс:
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUserName(username).orElseThrow(()->
new UsernameNotFoundException("No user name found named " + username));
return new org.springframework.security.core.userdetails.User(user.getUserName(),
user.getPassword(),
true,true,true,true,
getAuthorities("ROLE_USER"));
}
private Collection<? extends GrantedAuthority> getAuthorities(String role_user) {
return Collections.singletonList(new SimpleGrantedAuthority(role_user));
}
}
и мои application.properties:
spring.datasource.url=jdbc:mysql://localhost/photoblog?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=...username...
spring.datasource.password=...password...
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true