JwtAuthenticationFilter.java
package com.edtech.config;
import com.edtech.model.User;
import com.edtech.repository.UserRepository;
import com.edtech.service.JwtService;
import io.jsonwebtoken.JwtException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
/** Documentação para JwtAuthenticationFilter. */
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtService jwtService;
private final UserRepository userRepository;
/** Documentação para o método JwtAuthenticationFilter. */
public JwtAuthenticationFilter(
JwtService jwtService,
@org.springframework.context.annotation.Lazy UserRepository userRepository) {
this.jwtService = jwtService;
this.userRepository = userRepository;
}
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
String path = request.getServletPath();
String method = request.getMethod();
return HttpMethod.OPTIONS.matches(method)
|| (HttpMethod.POST.matches(method) && "/api/auth/login".equals(path))
|| (HttpMethod.POST.matches(method) && "/api/auth/register".equals(path))
|| path.startsWith("/api/auth/recovery/");
}
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
Optional<String> token = extractToken(request);
if (token.isEmpty()) {
filterChain.doFilter(request, response);
return;
}
try {
String email = jwtService.extractSubject(token.get());
if (email != null && SecurityContextHolder.getContext().getAuthentication() == null) {
userRepository
.findByEmailIgnoreCase(email)
.filter(User::isActive)
.filter(user -> jwtService.isValid(token.get(), user))
.ifPresent(user -> authenticateUser(request, user));
}
} catch (JwtException | IllegalArgumentException exception) {
SecurityContextHolder.clearContext();
}
filterChain.doFilter(request, response);
}
private Optional<String> extractToken(HttpServletRequest request) {
String authHeader = request.getHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer ")) {
return Optional.of(authHeader.substring(7));
}
return Optional.empty();
}
private void authenticateUser(HttpServletRequest request, User user) {
var authorities = List.of(new SimpleGrantedAuthority("ROLE_" + user.getRole().name()));
var authentication = new UsernamePasswordAuthenticationToken(user, null, authorities);
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}