Ya estoy inscrito ¿Todavía no tienes acceso? Nuestros Planes
Ya estoy inscrito ¿Todavía no tienes acceso? Nuestros Planes
2
respuestas

[Duda] verifier invalido

Buenas tardes, me encuentro en la ultima clase del segundo curso de spring boot, y tengo un problema al hacer el Get para listar los medicos. El login me da correcto y me da el token para colocar el en 'Bearer Token', pero aun cuando el token es correcto al listar los medicos en insomnia me sale 403 Forbidden, ademas del error en la imagen. Las lineas de codigo estan igual que el instructor.

A continuacion muestro el codigo de las clases involucradas en el error.

Clase Token Service:

@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())
                .sign(algorithm);
    } catch (JWTCreationException exception){
        throw  new RuntimeException("Error al generar el Token");
    }
}

public  String getSubject(String token) {
    if (token == null){
        throw new RuntimeException();
    }
    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
        System.out.println(exception.toString());
    }
    if (verifier.getSubject() == null) {
        System.out.println("3 aqui bien");
        throw new RuntimeException("verifier invalido");

    }
    System.out.println("3 aqui bien");
    return verifier.getSubject();

}

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

}

Clase SecurityFilter

@Component public class SecurityFilter extends OncePerRequestFilter {

@Autowired
private TokenService tokenService;

@Autowired
private UsuarioRepository usuarioRepository;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    //obtener tokene del header
    var authHeader = request.getHeader("Authorization");
    if (authHeader != null){
        var token = authHeader.replace("Bearer","");
        var nameUser = tokenService.getSubject(token);
        if (nameUser != null){
            //token valido
            System.out.println("6 aqui bien");
            var usuario = usuarioRepository.findByLogin(nameUser);
            var authentication = new UsernamePasswordAuthenticationToken(usuario, null,
                    usuario.getAuthorities()); //se fuerza el inicio de sesion
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }

    }
    filterChain.doFilter(request, response);

}

}

Ingrese aquí la descripción de esta imagen para ayudar con la accesibilidad

2 respuestas

Hola termine recién el curso pero creo que tienes unos detalles super pequeños que te pueden estar afectando:

en esta linea:

var authHeader = request.getHeader("Authorization"); 

yo use una clase de spring y este es el import y la linea:

import org.springframework.http.HttpHeaders;

var authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);

Esto solo para evitar el error de escritura.

Asi lo tienes tu:

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

Lo otro creo que te falta el espacio en el Bearer

así debería ir:

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

entiendo que al no tener el espacio no te logra extraer correctamente el token y de asi extraer el usuario para poder asignarlo.

prueba colocando unos System.out.println() de pasos igualmente para ver que después del cambio lo extraiga bien:

Algo asi:

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    //obtener tokene del header
    var authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
    if (authHeader != null){
        var token = authHeader.replace("Bearer ","");
        System.out.println(token);
        var nameUser = tokenService.getSubject(token);
        System.out.println(nameUser);
        if (nameUser != null){
            //token valido
            System.out.println("6 aqui bien");
            var usuario = usuarioRepository.findByLogin(nameUser);
            var authentication = new UsernamePasswordAuthenticationToken(usuario, null,
                    usuario.getAuthorities()); //se fuerza el inicio de sesion
            SecurityContextHolder.getContext().setAuthentication(authentication);

espero que. te sirva algo de ayuda, saludos

Muchas gracias por tu ayuda