ainda tomando erro 403, ja verifiquei o codigo e nao encontro o pq desse erro
E
Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!
ainda tomando erro 403, ja verifiquei o codigo e nao encontro o pq desse erro
E
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" );
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.
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!");
}
}

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

Ramon, coloquei como primeiro mas nada mudou
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
Parece que o problema é na senha.
Roda esse comando no seu banco de dados:
update usuarios set senha = '$2a$10$6USmofnjEc4AodqxRTrzTecI9ZCrrPuhGq0EaM0iu3iV3yp7WYnGa';
Feito