Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

[Bug] ERRO tokenService.getSubject retornando Null

Ao Enviar uma requisição HTTP GET solicitando a lista de médicos mandando o token gerado estou recebendo esse erro:

java.lang.NullPointerException: Cannot invoke "med.voll.api.infra.security.TokenService.getSubject(String)" because "this.tokenService" is null
    at med.voll.api.infra.security.SecurityFilter.doFilterInternal(SecurityFilter.java:31) ~[classes/:na]

O erro informa que ao chamar var subject = tokenService.getSubject(tokenJWT) está retornando null.

Já tentei algumas as sugestões do curso para correção porem sem sucesso =/

Segue trecho do código do SecurityFilter:

@Component
public class SecurityFilter extends OncePerRequestFilter {

  @Autowired
  private TokenService tokenService;

  @Autowired
  private UsuarioRepository repository;

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    var tokenJWT = recuperarToken(request);

    if (tokenJWT != null) {
      var subject = tokenService.getSubject(tokenJWT);
      var usuario = repository.findByLogin(subject);

      var authentication = new UsernamePasswordAuthenticationToken(usuario, null, usuario.getAuthorities());
      SecurityContextHolder.getContext().setAuthentication(authentication);
    }

    filterChain.doFilter(request, response);
  }

Trecho do código do TokenService:

public String getSubject(String tokenJWT) {
    try {
      var algoritmo = Algorithm.HMAC256(secret);
      return JWT.require(algoritmo)
              .withIssuer("API Voll.med")
              .build()
              .verify(tokenJWT)
              .getSubject();
    } catch (JWTVerificationException exception) {
      throw new RuntimeException("Token JWT inválido ou expirado!");
    }
  }

Aqui está o link do git caso precise, desde já obrigado!!!!!!! https://github.com/AguiarIsaac/API_Alura_Curso_Java

3 respostas

Olá Isaac!

O erro "java.lang.NullPointerException: Cannot invoke "med.voll.api.infra.security.TokenService.getSubject(String)" because "this.tokenService" is null" indica que a instância do serviço TokenService não está sendo devidamente injetada no filtro SecurityFilter. Isso pode acontecer por algumas razões:

  1. Falha na configuração da injeção de dependência: Verifique se a classe TokenService está devidamente anotada com @Service ou @Component, ou outra anotação que faça o Spring reconhecê-la como um componente gerenciado pelo contêiner de injeção de dependência.

  2. Verifique a classe de configuração do Spring: Certifique-se de que a classe de configuração do Spring (normalmente anotada com @Configuration) esteja corretamente configurada para fazer a varredura e detecção de componentes. Você pode fazer isso utilizando a anotação @ComponentScan e fornecendo o pacote base onde suas classes estão localizadas. Por exemplo:

@Configuration
@ComponentScan("med.voll.api")
public class AppConfig {
    // Configurações adicionais aqui...
}
  1. Verifique se a classe SecurityFilter está sendo corretamente gerenciada pelo Spring. Certifique-se de que a anotação @Component esteja presente nessa classe.

  2. Verifique se o TokenService não possui uma configuração específica que esteja impedindo a injeção correta. Por exemplo, se você estiver utilizando algum perfil específico no Spring, verifique se a configuração do TokenService não está condicionada a esse perfil.

  3. Verifique se não há outra classe ou componente que está substituindo ou anulando a injeção do TokenService.

Após verificar esses pontos, você deve conseguir corrigir o problema de null pointer exception e permitir que o tokenService seja devidamente injetado no SecurityFilter. Certifique-se também de que a classe TokenService esteja corretamente configurada para fornecer o valor do secret, pois caso o secret esteja nulo, o método JWT.require(algoritmo) pode lançar outra exceção, causando outro possível null pointer exception.

solução!

Oi!

Verifica na sua classe SecurityConfigurations se o SecurityFilter foi injetado. Talvez você esteja instanciando manualmente.

Exatamente Professor!! Muito obrigado!!

Código após a correção certeira:

// Não tinha injetado o securityFilter
@Autowired
  private SecurityFilter securityFilter;

  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

    //Estava assim
    //SecurityFilter securityFilter = new SecurityFilter();

    return http.csrf(csrf -> csrf.disable())
            .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(req -> {
              req.requestMatchers(HttpMethod.POST, "/login").permitAll();
              req.anyRequest().authenticated();
            })
            .addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class)
            .build();
  }