1
resposta

Erro Requisição Post Forbbiden

Estou fazendo requisições post passando o Token, todavia, reparei que, ao passar o Token corretamente, ele funciona, somente na requisição Post que não. Testei com o Get, Put e delete, e ele retornou 200 ok, quando tento fazer requisição p post, ele rretornar com 403 forbbiden.

Segue abaixo os códigos:

Controller:

@RestController
@RequestMapping("/login")
public class AutenticacaoController {
@Autowired //injetar o parametro
    private AuthenticationManager manager;

@Autowired
private TokenService tokenservice;

    public AutenticacaoController(TokenService tokenservice) {
        this.tokenservice = tokenservice;
    }

    @PostMapping
    public ResponseEntity logar(@RequestBody @Valid DadosAutenticacao dados) {
        try {
            var token = new UsernamePasswordAuthenticationToken(dados.login(), dados.senha());
        var autenticacao = manager.authenticate(token);

        var TokenJWT = tokenservice.gerarToken((usuario) autenticacao.getPrincipal());

        return ResponseEntity.ok(new DadosTokenJWT(TokenJWT)); }
        catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().body(e.getMessage());
        }

    }
}

COnfiguração seguranca

@Configuration //anotação de configuração
@EnableWebSecurity // Informar ao Spring que será realizado uma personalização nas configurações de segurança


public class ConfiguracaoSecurity {

    @Autowired
    private FiltroSeguranca filtroSeguranca;
    @Bean
    public SecurityFilterChain security(HttpSecurity http) throws Exception {

        return http.csrf(csrf -> csrf.disable())
                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeHttpRequests(req -> {
                    req.requestMatchers("/login").permitAll();
                    req.anyRequest().authenticated();
                })
                .addFilterBefore(filtroSeguranca, UsernamePasswordAuthenticationFilter.class)
                .build();
    }

    @Bean
    public AuthenticationManager autentica(AuthenticationConfiguration configuration) throws Exception {
        return configuration.getAuthenticationManager();
    }

    @Bean

    public PasswordEncoder senhasScript() {
        return new BCryptPasswordEncoder();
    }
}

public record DadosTokenJWT(String tokenJWT) {
}

FIltro:

@Component
public class FiltroSeguranca extends OncePerRequestFilter {

    @Autowired
    private TokenService tokenservice;
    @Autowired
    private UsuarioRepository repositoryusuario;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { //validar apenas uma vez por request
        var token = recuperaToken(request);
        if (token != null) {
            var login = tokenservice.getSubject(token);
            var usuario = repositoryusuario.findByLogin(login);

            var autenticacao = new UsernamePasswordAuthenticationToken(usuario, null, usuario.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(autenticacao);

        }

        filterChain.doFilter(request, response);

    }

    private String recuperaToken(HttpServletRequest request) {
        var autorizacao = request.getHeader("Authorization");
        if(autorizacao != null) {
            return autorizacao.replace("Bearer", "");
        }

        return null;
    }
}

Token Service:

@Service
public class TokenService {

    @Value("${api.security.token.secret}")
    private String secret;
    public String gerarToken(usuario usuario) {
        try {
            var algoritmo = Algorithm.HMAC256(secret);
            return JWT.create()
                    .withIssuer("API VOLL.med")
                    .withSubject(usuario.getLogin())
                    .withExpiresAt(dataExpiracao())
                    .sign(algoritmo);
        } catch (JWTCreationException exception){
           throw new RuntimeException("erro ao gerar token jwt", exception);
        }
    }


    public String getSubject(String tokenJWT) {
        try {
            var algoritmo = Algorithm.HMAC256(secret);
            return  JWT.require(algoritmo)
                    .withIssuer("API VOLL.med")
                    .build()
                    .verify(tokenJWT)
                    .getSubject();

        } catch (JWTVerificationException exception){
            throw new RuntimeException("Token JWT invalido ou expirado! :(");
        }
    }


    private Instant dataExpiracao() {
        return LocalDateTime.now().plusHours(2).toInstant(ZoneOffset.of("-03:00"));
    }
}
1 resposta

Olá, Felipe!

Pelo que pude analisar em seu código, acredito que o problema esteja relacionado com a forma como você está recuperando o token no filtro de segurança. No método recuperaToken(HttpServletRequest request), você faz a substituição do prefixo "Bearer" por uma string vazia. No entanto, você não está removendo os espaços em branco que podem estar presentes após o prefixo "Bearer". Isso pode estar causando a falha na autenticação e, consequentemente, o retorno do erro 403 Forbidden.

Sugiro que você modifique a linha de código que faz a substituição do prefixo "Bearer" para remover também os espaços em branco. Aqui está um exemplo de como você pode fazer isso:

return autorizacao.replace("Bearer ", "");

Note o espaço em branco após "Bearer". Isso deve remover o prefixo "Bearer" e também o espaço em branco que o segue.

Outra forma é utilizar o método trim() para remover os espaços em branco:

return autorizacao.replace("Bearer", "").trim();

Lembre-se de que essa é apenas uma sugestão baseada na análise do seu código e pode não resolver completamente o problema. Recomendo que você teste essa modificação e veja se o problema persiste.

Espero ter ajudado e bons estudos!