Solucionado (ver solución)
Solucionado
(ver solución)
2
respuestas

[Duda] Error con getSubject (Verifier invalido)

Buenas, tengo un problema, yo le paso un token valido recien creado en el meotodo GET de listar medicos y me da el siguiente error:

(la primer linea es mi token)

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ2b2xsIG1lZCIsInN1YiI6ImtldmluIiwiaWQiOjEsImV4cCI6MTY5NDc4ODY5N30.FCc-RCp_Q28YG02xL2WqVcg2B51BhT-utbd-loHwWmA 
com.auth0.jwt.exceptions.JWTDecodeException: The input is not a valid base 64 encoded string.
2023-09-15T09:42:04.601-03:00 ERROR 2920 --- [p-nio-80-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

java.lang.RuntimeException: Verifier invalido.
        at med.voll.api.infra.security.TokenService.getSubject(TokenService.java:52) ~[classes/:na]
        at med.voll.api.infra.security.SecurityFilter.doFilterInternal(SecurityFilter.java:28) ~[classes/:na]      
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.11.jar:6.0.11]

pero no se por que es, y mi metodo GetSubject es el siguiente:

package med.voll.api.infra.security;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

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;

@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.getNombre())
                .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);
        }catch(JWTVerificationException e){
            System.out.println(e.toString());
        }
        if(verifier == null || verifier.getSubject() == null)
            throw new RuntimeException("Verifier invalido.");
        return verifier.getSubject();
        
    }

    private Instant generarFechaExpiracion(int hours){
        return LocalDateTime.now().plusHours(hours).toInstant(ZoneOffset.of("-03:00"));
    }
}

aca esta mi filtro:

@Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException{
        var token = request.getHeader("Authorization");
        if( token == null || token.trim().isEmpty())
            throw new RuntimeException("El token enviado es invalido.");
        token.replace("Bearer ", "");
        System.out.println(token);
        System.out.println(tokenService.getSubject(token));

        filterChain.doFilter(request, response);
    }

y no se que es lo que esta mal, desde ayer tengo el error y no se como solucionarlo, entiendo que entra en el catch pero no se como evitarlo.. Alguien sabe algo de esto?

2 respuestas
solución!

Ya encontre la solucion jajaj, comento mi error por si a alguien le sirve, cuando ejecutaba la a sgte linea en SecurityFilter

token.replace("Bearer ", "");

no me funcionaba por que el método replace no cambia la variable original, sino que retorna un String nuevo, entonces debo volver a guardarlo en la variable token así:

token =  token.replace("Bearer ", "");

Grande Grande ♥