2
respostas

Dúvida Sobre implementação do Servico

Boa noite pessoal, estou tentando implementar a lógica aprendida no Curso em uma outra aplicação a fim de reforçar os conteudos aprendidos, contudo, estou tendo um erro que não estou sabendo resolver:

Field authenticationManager in edu.corp.api.domain.controllers.AutenticacaoController required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found.
The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)
    - @org.springframework.beans.factory.annotation.Qualifier("authenticationManagerBean")
Action:
Consider defining a bean of type 'org.springframework.security.authentication.AuthenticationManager' in your configuration.
Process finished with exit code 0
package edu.corp.api.utils.infra.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class securityConfiguration{
    @Autowired
    private securityFilter securityFilter;

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManagerBean;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
                .csrf(csrf -> csrf.disable())
                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeRequests(authorizeRequests ->
                        authorizeRequests
                                .requestMatchers(HttpMethod.POST, "/login").permitAll()
                                .requestMatchers("/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**").authenticated()
                                .anyRequest().authenticated()
                )
                .addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class)
                .build();
    }
}

AutenticacaoController:

package edu.corp.api.domain.controllers;

import edu.corp.api.domain.dtos.autenticacao.LoginDTO;
import edu.corp.api.domain.models.Usuario;
import edu.corp.api.utils.infra.security.TokenJWT;
import edu.corp.api.utils.infra.security.TokenService;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.http.ResponseEntity;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AutenticacaoController {
    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;
    // Classe para disparar o servico de autenticacao

    @Autowired
    private TokenService tokenService;

    @PostMapping
    public ResponseEntity efetuarLogin(@RequestBody @Valid LoginDTO login){
        try{
            // DTO do Spring Security para dados de authenticacao
            var authenticationToken = new UsernamePasswordAuthenticationToken(login.email(), login.senha());
            var authentication = authenticationManager.authenticate(authenticationToken);

            var tokenJWT = tokenService.generateToken((Usuario) authentication.getPrincipal());

            return ResponseEntity.ok(new TokenJWT(tokenJWT));
        } catch (Exception e){
            return ResponseEntity.badRequest().body(e.getMessage());
        }
    }
}
2 respostas

Bom dia, Samuel! Como vai?

O erro diz que não foi possível encontrar um bean do tipo AuthenticationManager no seu contexto de configuração.

Uma possível solução para esse problema é adicionar a configuração do AuthenticationManager na sua classe securityConfiguration. Você pode fazer isso criando um método com a anotação @Bean que retorna uma instância de AuthenticationManager, como no exemplo abaixo:

@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

Dessa forma, o Spring irá criar um bean do tipo AuthenticationManager e você poderá injetá-lo no seu AutenticacaoController utilizando a anotação @Autowired e @Qualifier("authenticationManagerBean"), como você já está fazendo.

Além disso, observe que o código que você compartilhou está utilizando uma versão mais recente do Spring Boot (3.1) e algumas configurações foram alteradas em relação à segurança. No exemplo que você compartilhou, o método securityFilterChain deve ser alterado para:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    return http
            .csrf(csrf -> csrf.disable())
            .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .build();
}

Essa alteração é necessária caso você esteja utilizando o Spring Boot 3.1 ou versões posteriores.

Espero que essas sugestões possam te ajudar a resolver o erro. Se tiver mais alguma dúvida, estou aqui para ajudar.

Grande abraço e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.

Olá Armano, boa noite.

No caso, o Intellij não reconheceu o método super.authenticationManagerBean(). Essa interface está relacionada à dependência do Spring Security?