Estou em um projeto a qual estou me baseando a autenticação a que foi feita no curso, no caso com sua variação de duas entidades e com a versão do spring 3.0.5
Seguindo os passos do curso, recebi a exception java.lang.StackOverflowError: null
ele dá erro no AutenticaçãoController
var authentication = manager.authenticate(token);
parece que o AuthenticationManager não é injetado pelo anotação @Autowired segue o erro abaixo:
2023-06-27T10:33:36.642-03:00 ERROR 12809 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed: java.lang.StackOverflowError] with root cause
java.lang.StackOverflowError: null
at java.base/java.lang.Exception.<init>(Exception.java:103) ~[na:na]
at java.base/java.lang.ReflectiveOperationException.<init>(ReflectiveOperationException.java:90) ~[na:na]
at java.base/java.lang.reflect.InvocationTargetException.<init>(InvocationTargetException.java:67) ~[na:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[spring-aop-6.0.7.jar:6.0.7]
Segue abaixo as classes AutentiçãoController:
@RestController
@RequestMapping("/login")
public class AutenticacaoController {
@Autowired
private AuthenticationManager manager;
@PostMapping
public ResponseEntity efetuarLoginCliente(@RequestBody @Valid DadosAutenticacao dados){
var token = new UsernamePasswordAuthenticationToken(dados.login(), dados.senha());
System.out.println("passei aqui??");
var authentication = manager.authenticate(token);
return ResponseEntity.ok().build();
}
}
Os Models Cliente e Funcionário com UserDetails implementado.
@Entity(name = "clientes")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of="id")
public class Cliente implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String login;
private String senha;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return List.of(new SimpleGrantedAuthority("ROlE_USER"));
}
@Override
public String getPassword() {
return senha;
}
@Override
public String getUsername() {
return login;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
@Table(name="funcionarios")
@Entity(name = "Funcionarios")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of="id")
public class Funcionario implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String login;
private String senha;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return List.of(new SimpleGrantedAuthority("ROLE_USER"));
}
@Override
public String getPassword() {
return senha;
}
@Override
public String getUsername() {
return login;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
e por fim a classe SecurityConfigurations, já que através do método authenticationManager
que vai ser gerado o AuthenticationManager lá para o controller
@Configuration
@EnableWebSecurity
public class SecurityConfigurations {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
return http.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().build();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception{
return configuration.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
Obs: fiz apenas o login para o cliente, ainda não fiz a para o funcionário.