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

[Duda] The input is not a valid base 64 encoded string.

No logro la validación del token.

Antes de implementar el método getSubject no me generaba error, tengo implementados todos los métodos y las clases deacuerdo al repocitorio final en estos momentos estoy generando el token sin hora de vencimiento para restarle variables, estos son algunos resultados.

Este es el resultado de la variable apiSecret cuando se genera el token apiSecret Antes del JWT.create()) 123456

Este es el token generado Antes del if doFilterInternal Bearer "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJDYXJsb3MuR29tZXoiLCJpc3MiOiJ2b2xsIG1lZCIsImlkIjoxfQ.RNJz8m2QZRh4NOWrEVEI51VtOR7797HqcQLiygkWJV4"

Este es el token que resulta del replace Despues del replace "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJDYXJsb3MuR29tZXoiLCJpc3MiOiJ2b2xsIG1lZCIsImlkIjoxfQ.RNJz8m2QZRh4NOWrEVEI51VtOR7797HqcQLiygkWJV4"

Este es el token y la variable apiSecret dentro del método getSubject token Antes del JWT.require(algorithm) "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJDYXJsb3MuR29tZXoiLCJpc3MiOiJ2b2xsIG1lZCIsImlkIjoxfQ.RNJz8m2QZRh4NOWrEVEI51VtOR7797HqcQLiygkWJV4" apiSecret Antes del JWT.require(algorithm) 123456

Este es el token dentro de la excepción Dentro del catch "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJDYXJsb3MuR29tZXoiLCJpc3MiOiJ2b2xsIG1lZCIsImlkIjoxfQ.RNJz8m2QZRh4NOWrEVEI51VtOR7797HqcQLiygkWJV4"

Esta es la excepción No fue posible verificar com.auth0.jwt.exceptions.JWTDecodeException: The input is not a valid base 64 encoded string.

Por su atención gracias.

@Service
public class TokenService {

    @Value("${api.security.secret}")
    private String apiSecret;

    public String generarToken(Usuario usuario) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(apiSecret);
            System.out.println("apiSecret Antes del JWT.create()) " + apiSecret);
            return JWT.create()
                    .withIssuer("voll med")
                    .withSubject(usuario.getLogin())
                    .withClaim("id", usuario.getId())
                   // .withExpiresAt(generarFechaExpiracion())
                    .sign(algorithm);
        } catch (JWTCreationException exception){
            throw new RuntimeException();
        }
    }

    public String getSubject(String token) {
        if (token == null) {
            System.out.println("en el  if null " + token );
            throw new RuntimeException();
        }
        DecodedJWT verifier = null;
        try {
            Algorithm algorithm = Algorithm.HMAC256(apiSecret); // validando firma
            System.out.println("token Antes del JWT.require(algorithm) " + token );
            System.out.println("apiSecret Antes del JWT.require(algorithm) " + apiSecret);
            verifier = JWT.require(algorithm)
                    .withIssuer("voll med")
                    .build()
                    .verify(token);
            verifier.getSubject();
        } catch (JWTVerificationException exception) {
            System.out.println(" token Dentro del catch " + token );
            System.out.println("Dentro del catch " + apiSecret);
            System.out.println("No fue posible verificar "+exception.toString());
        }
        if (verifier.getSubject() == null) {
            throw new RuntimeException("Verifier invalido");
        }
        return verifier.getSubject();
    }
@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 el token del header
        var authHeader = request.getHeader("Authorization");
        System.out.println("Antes del if doFilterInternal "+ authHeader);
        if (authHeader != null) {
            var token = authHeader.replace("Bearer ", "");
            System.out.println("Despues del replace " + token );
            var nombreUsuario = tokenService.getSubject(token); // extract username
            if (nombreUsuario != null) {
                // Token valido
                var usuario = usuarioRepository.findByLogin(nombreUsuario);
                var authentication = new UsernamePasswordAuthenticationToken(usuario, null,
                        usuario.getAuthorities()); // Forzamos un inicio de sesion
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
        filterChain.doFilter(request, response);
    }
}
2 respuestas

Buenos días Carlos Omar Gómez Cebrián como esta tu código en SecurityConfigurations.java puede que tu problema este en alguna linea de código de dicha implementación.

Compara con esta implementación del Código que nos aporta un colega de la comunidad, espero te ayude, ya que al observa tu codigo esta muy de la par con lo que se explica en los videos, bendiciones

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

solución!

Muchas gracias por el aporte Eder Darío Hernández España , lo implemente y no funciono.

Ya se soluciono el problema es que el token de insomnia lo estaba colocando con comillas dobles, solo le quite las comillas y ya no presento falla.

Por su atención Gracias. Saludos

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        return httpSecurity
                .csrf(csrf -> csrf.disable())
                .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers(HttpMethod.POST, "/login").permitAll()
                        .anyRequest().authenticated())
                .addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class)
                .build();
    }


    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration)
            throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {

        return new BCryptPasswordEncoder();
    }

}