Estoy enfrentando el problema que al momento de ejecutar la consulta con el Insomnia me muestra el error de que el verifier es null. Estuve buscando en el foro algunas posibles respuestas, pero ninguna nos funcionó, así que le comparto el código para que también puedan ayudar a solventarlo, gracias. Este es el error que obtengo:
2023-09-23T22:32:50.635-06:00 ERROR 25082 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
java.lang.NullPointerException: Cannot invoke "com.auth0.jwt.interfaces.DecodedJWT.getSubject()" because "verifier" is null
at med.voll.api.infra.security.TokenService.getSubject(TokenService.java:46) ~[classes/:na]
at med.voll.api.infra.security.SecurityFilter.doFilterInternal(SecurityFilter.java:29) ~[classes/:na]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.0-M4.jar:6.1.0-M4]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231) ~[spring-security-web-6.2.0-M2.jar:6.2.0-M2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365) ~[spring-security-web-6.2.0-M2.jar:6.2.0-M2]
Esta es la clase TokenService.java
package med.voll.api.infra.security;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import med.voll.api.domain.usuarios.Usuario;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
@Service
public class TokenService {
@Value("${api.security.secret}")
private String apiSecret;
public String generarToken(Usuario usuario) {
try {
Algorithm algorithm = Algorithm.HMAC256(apiSecret);
return JWT.create()
.withIssuer("voll med")
.withSubject(usuario.getLogin())
.withClaim("id", usuario.getId())
.withExpiresAt(generarFechaExpiracion(2))
.sign(algorithm);
} catch (JWTCreationException exception){
throw new RuntimeException();
}
}
public String getSubject(String token) {
DecodedJWT verifier = null;
try {
Algorithm algorithm = Algorithm.HMAC256(apiSecret);
verifier = JWT.require(algorithm)
.withIssuer("voll med")
.build()
.verify(token);
verifier.getSubject();
} catch (JWTVerificationException exception) {
// Invalid signature/claims
}
if (verifier.getSubject() == null){
throw new RuntimeException("verifier inválido");
}
return verifier.getSubject();
}
private Instant generarFechaExpiracion(int hours) {
return LocalDateTime.now().plusHours(hours).toInstant(ZoneOffset.of("-06:00"));
}
}
Y esta es la clase SecurityFilter.java
package med.voll.api.infra.security;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
@Component
public class SecurityFilter extends OncePerRequestFilter {
@Autowired
private TokenService tokenService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("The filter its being invoked");
var token = request.getHeader("Authorization");//.replace("Bearer ", "");
if (token == null || token == ""){
throw new RuntimeException("El token enviado no es valido");
}
token = token.replace("Bearer ", "");
System.out.println(token);
System.out.println(tokenService.getSubject(token));
filterChain.doFilter(request, response);
}
}
Les agradeceré muchísimo cualquier tipo de ayuda pues ya llevo varios días con este problema: Gracias de antemano por la ayuda.