Ya estoy inscrito ¿Todavía no tienes acceso? Nuestros Planes
Ya estoy inscrito ¿Todavía no tienes acceso? Nuestros Planes
Solucionado (ver solución)
Solucionado
(ver solución)
1
respuesta

error 403 Forbidden

Hola buenas tardes, tengo este problema y no lo he podido solucionar, agradezco si me pueden ayudar porque en el metodo get no me aparecen el listado de medicos, gracias. adjunto fotos y los codigos de las clases.

Gracias!


@Configuration
@EnableWebSecurity
public class SecurityConfigurations {

    @Autowired
    private SecurityFilter securityFilter;

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

        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();
    }

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

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

}

@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 {
        System.out.println("el filtro esta siendo llamado");

        //obtener el token del header
        var autHeader  = request.getHeader("Authorization");
        if(autHeader != null){
            var token = autHeader.replace("Bearer ", "");
            var nombreUsuario = tokenService.getSubject(token);
            if (nombreUsuario != null) {
                //token valido
                var usuario = usuarioRepository.findByLogin(nombreUsuario);
                var authentication = new UsernamePasswordAuthenticationToken(usuario, null, usuario.getAuthorities());
                usuarioRepository.findByLogin(nombreUsuario);
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
        filterChain.doFilter(request, response);
    }
}

@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();

        }
    }

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

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

}

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

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

1 respuesta
solución!

¡Hola Luis!

Entiendo que estás experimentando el error 403 Forbidden al intentar obtener el listado de médicos a través de un método GET en tu API Rest. Parece que el problema radica en la configuración de los filtros de seguridad en tu aplicación Spring Boot.

Por lo que puedo ver en tu código, parece que has implementado un filtro de seguridad personalizado llamado SecurityFilter, el cual extiende de OncePerRequestFilter. Sin embargo, parece que este filtro no está siendo llamado antes que el filtro por defecto de Spring, lo que está causando que tus solicitudes sean bloqueadas.

Para solucionar este problema, necesitas asegurarte de que tu filtro personalizado se ejecute antes que el filtro por defecto de Spring. Puedes lograr esto utilizando el método addFilterBefore en tu configuración de seguridad. Aquí tienes un ejemplo de cómo podrías hacerlo:

http.addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class);

Al agregar esta línea en tu método securityFilterChain dentro de la clase SecurityConfigurations, le estás indicando a Spring que ejecute tu filtro personalizado antes que el filtro por defecto.

Además, parece que estás utilizando un enfoque stateless para la gestión de sesiones. Es importante asegurarte de que estás manejando correctamente la autenticación de los usuarios en un entorno stateless. Asegúrate de que el token se esté enviando correctamente en las solicitudes y de que esté siendo validado apropiadamente en tu filtro personalizado.

Espero que estas sugerencias te ayuden a resolver el problema del error 403 Forbidden en tu API Rest. Si necesitas más ayuda, no dudes en preguntar.

¡Espero haber ayudado y buenos estudios!

Si este post te ayudó, por favor, marca como solucionado ✓. Continúa con tus estudios!