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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
@Service
public class TokenService {
private static final Logger logger = LoggerFactory.getLogger(TokenService.class);
@Value("${api.security.token.secret}")
private String secret;
public String gerarToken(Usuario usuario) {
try {
if (secret == null || secret.isEmpty()) {
throw new IllegalStateException("Secret for JWT is not configured");
}
var algoritmo = Algorithm.HMAC256(secret);
String token = JWT.create()
.withIssuer("API Voll.med")
.withSubject(usuario.getLogin())
.withExpiresAt(dataExpiracao())
.sign(algoritmo);
logger.info("Token gerado com sucesso: {}", token);
return token;
} catch (JWTCreationException exception) {
logger.error("Erro ao gerar token JWT", exception);
throw new RuntimeException("Erro ao gerar token JWT", exception);
}
}
public String getSubject(String tokenJWT) {
try {
if (secret == null || secret.isEmpty()) {
throw new IllegalStateException("Secret for JWT is not configured");
}
var algoritmo = Algorithm.HMAC256(secret);
String subject = JWT.require(algoritmo)
.withIssuer("API Voll.med")
.build()
.verify(tokenJWT)
.getSubject();
logger.info("Token verificado com sucesso. Subject: {}", subject);
return subject;
} catch (JWTVerificationException exception) {
logger.error("Token JWT inválido ou expirado!", exception);
throw new RuntimeException("Token JWT inválido ou expirado!", exception);
}
}
private Instant dataExpiracao() {
return LocalDateTime.now().plusHours(4).toInstant(ZoneOffset.of("-03:00"));
}
}
SECUTIRYFILTER
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
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.getSubject(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;
}
}