23
respostas

Error 403

ainda tomando erro 403, ja verifiquei o codigo e nao encontro o pq desse erro Insira aqui a descrição dessa imagem para ajudar na acessibilidade E

23 respostas

tokenService

package med.voll.API.infra.security;

import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTCreationException; import com.auth0.jwt.exceptions.JWTVerificationException; import med.voll.API.domain.usuario.Usuario; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service;

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

@Service public class TokenService {

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

public String gerarToken(Usuario usuario) {
    System.out.println(secret);
    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 gerrar token jwt", exception);
    }
}

public String getSubjec(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 inválido ou expirado!");
    }
}
    private Instant dataExpiracao() {
        return LocalDateTime.now().plusHours(2).toInstant(ZoneOffset.of("-03:00"));
    }
}

securityFilter

package med.voll.API.infra.security;

import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import med.voll.API.domain.usuario.UsuarioRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

@Component//serve para que o spring rode um componente generico public class SecurityFilter extends OncePerRequestFilter {

@Autowired
private TokenService tokenService;

@Autowired
private UsuarioRepository repository;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {


    var tokenJWT = recuperarToken(request);

    if (tokenJWT != null) {
        var subject = tokenService.getSubjec(tokenJWT);
        var usuario = repository.findByLogin(subject);

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

    filterChain.doFilter(request, response);
}

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

}

securityConfiguration

package med.voll.API.infra.security;

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.DefaultSecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@EnableWebSecurity @Configuration//classe configuracoes de seguranca public class SecurityConfigurations {

@Autowired
private SecurityFilter securityFilter;

@Bean
public DefaultSecurityFilterChain SecurityFilterChain (HttpSecurity http) throws Exception {
    return http.csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and().authorizeHttpRequests()
            .requestMatchers(HttpMethod.POST, "/login").permitAll()
            .anyRequest().authenticated()
            .and().addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class)
            .build();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception{
    return configuration.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
}

}

@Bean public DefaultSecurityFilterChain SecurityFilterChain (HttpSecurity http) throws Exception

nessa parte acima o intellij me obrigou a colocar esse ( DefaultSecurityFilterChain )

Oi Thiago!

O problema está no seu método recuperarToken da classe SecurityFilter:

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

Faltou um espaço em branco depois da palavra Bearer:

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

eu coloquei esse espaço e ainda to tomando esse erro

Coloca um system.out para ver no console o token que está chegando:

var tokenJWT = recuperarToken(request);

System.out.println("\n\n\n TOKEN QUE CHEGOU NA API: " +tokenJWT +"\n\n\n" );

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Está aí o problema, não está chegando o token mesmo :D

Como chegou undefined, vou chutar que você está disparando a requisição por uma aplicação frontend, então o erro está no envio da requisição no código do frontend em si.

to usando o insomnia

manda um print aqui da requisição no insomnia.

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Ah sim, é na requisição de login, que não tem token mesmo.

Geralmente dá 403 quando envia um login/senha que não está cadastrado no banco de dados. Coloca esse try catch no controller para verificar:

@PostMapping
public ResponseEntity efetuarLogin(@RequestBody @Valid DadosAutenticacao dados) {
    try {
        var authenticationToken = new UsernamePasswordAuthenticationToken(dados.login(), dados.senha());
        var authentication = manager.authenticate(authenticationToken);

        var tokenJWT = tokenService.gerarToken((Usuario) authentication.getPrincipal());

        return ResponseEntity.ok(new DadosTokenJWT(tokenJWT));
    } catch(Exception e) {
        System.out.println("\n\n\n ERRO AO FAZER LOGIN: \n\n\n")
        e.printStackTrace();

        return ResponseEntity.badRequest().body("erro de autenticacao!");
    }
}

Insira aqui a descrição dessa imagem para ajudar na acessibilidadeInsira aqui a descrição dessa imagem para ajudar na acessibilidade Insira aqui a descrição dessa imagem para ajudar na acessibilidade

A consulta devolveu null, então no seu banco de dados, na tabela de usuarios, não deve ter esse login que você está enviando: joao.carlos@voll.med ou a senha que você mandou está incorreta.

Faz um select na sua tabela de usuários para verificar.

você poderia bota o @valid como o primeiro parâmetro na assinatura da funçao ? public ResponseEntity efetuarLogin(@Valid @RequestBody DadosAutenticacao dados) {

entao, eu tava justamente testando outros logins pra ver se ia, mas todos dao erro Insira aqui a descrição dessa imagem para ajudar na acessibilidadeInsira aqui a descrição dessa imagem para ajudar na acessibilidade

Ramon, coloquei como primeiro mas nada mudou

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

O problema é que você está testando com os emails da tabela de medicos, mas na verdade deveria ser da tabela de usuarios.

Na sua tabela de usuarios so tem 2 logins:

ana.albuquerque@med e paulo.albuquerque@med

eu utilizei os da tabela de usuarios tbm, mesmo erro Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Parece que o problema é na senha.

Roda esse comando no seu banco de dados:

update usuarios set senha = '$2a$10$6USmofnjEc4AodqxRTrzTecI9ZCrrPuhGq0EaM0iu3iV3yp7WYnGa';

Feito