fix: corrige erro de permissao no login

- Adiciona try-catch no loadUserByUsername do FiltroJwt para
  evitar 500 quando token referencia usuario deletado
- Expande shouldNotFilter para pular endpoints publicos e imagens
- Corrige login.html para limpar tokens expirados antes de
  redirecionar ao calendario, prevenindo redirect loop
This commit is contained in:
2026-05-26 20:22:43 -03:00
parent 02cfd71cf4
commit 771ea7e9a9
2 changed files with 53 additions and 15 deletions
@@ -5,6 +5,8 @@ import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
@@ -17,6 +19,8 @@ import java.io.IOException;
@Component @Component
public class FiltroJwt extends OncePerRequestFilter { public class FiltroJwt extends OncePerRequestFilter {
private static final Logger log = LoggerFactory.getLogger(FiltroJwt.class);
private final UtilJwt utilJwt; private final UtilJwt utilJwt;
private final UserDetailsService userDetailsService; private final UserDetailsService userDetailsService;
@@ -30,8 +34,11 @@ public class FiltroJwt extends OncePerRequestFilter {
String path = request.getRequestURI(); String path = request.getRequestURI();
return path.equals("/") || path.equals("/index.html") || path.equals("/favicon.ico") return path.equals("/") || path.equals("/index.html") || path.equals("/favicon.ico")
|| path.startsWith("/static/") || path.startsWith("/css/") || path.startsWith("/js/") || path.startsWith("/static/") || path.startsWith("/css/") || path.startsWith("/js/")
|| path.startsWith("/img/") || path.endsWith(".css") || path.endsWith(".js") || path.startsWith("/img/") || path.startsWith("/imagens/")
|| path.endsWith(".ico") || path.endsWith(".html"); || path.startsWith("/api/estudantes/login") || path.startsWith("/api/estudantes/cadastro")
|| path.endsWith(".css") || path.endsWith(".js")
|| path.endsWith(".ico") || path.endsWith(".html") || path.endsWith(".png")
|| path.endsWith(".svg");
} }
@Override @Override
@@ -44,16 +51,21 @@ public class FiltroJwt extends OncePerRequestFilter {
if (header != null && header.startsWith("Bearer ")) { if (header != null && header.startsWith("Bearer ")) {
token = header.substring(7); token = header.substring(7);
estudanteId = utilJwt.getEstudanteIdFromToken(token);
} }
if (estudanteId != null && SecurityContextHolder.getContext().getAuthentication() == null) { if (token != null && utilJwt.validateToken(token)) {
UserDetails userDetails = userDetailsService.loadUserByUsername(estudanteId); estudanteId = utilJwt.getEstudanteIdFromToken(token);
if (utilJwt.validateToken(token)) { if (SecurityContextHolder.getContext().getAuthentication() == null) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( try {
userDetails, null, userDetails.getAuthorities()); UserDetails userDetails = userDetailsService.loadUserByUsername(estudanteId);
SecurityContextHolder.getContext().setAuthentication(authentication); UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (Exception e) {
log.warn("Falha ao carregar usuario do token (id={}): {}", estudanteId, e.getMessage());
SecurityContextHolder.clearContext();
}
} }
} }
+32 -6
View File
@@ -7,15 +7,17 @@
<link rel="stylesheet" href="login.css"> <link rel="stylesheet" href="login.css">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
<title>Login Focus Agenda</title> <title>Login Focus Agenda</title>
<script src="theme.js"></script>
</head> </head>
<body> <body>
<div id="topo"> <div id="topo">
<h1 id="textotop">Focus Agenda</h1> <h1 id="textotop">Focus Agenda</h1>
<button class="theme-toggle-btn" onclick="toggleTheme()" title="Tema Escuro"><img src="imagens/moon-svgrepo-com.svg" class="theme-icon" alt="Tema"></button>
</div> </div>
<div id="log"> <div id="log">
<h1 class="mens">Bem-vindo!</h1> <h1 class="mens">Bem-vindo!</h1>
<h3 class="mens">Faça seu login</h3> <h3 class="mens">Faca seu login</h3>
<div id="mensagem-erro" role="alert"></div> <div id="mensagem-erro" role="alert"></div>
@@ -35,10 +37,35 @@
</div> </div>
<script> <script>
// Se já tiver token válido, redireciona direto
(function () { (function () {
if (localStorage.getItem('fa_token')) { const params = new URLSearchParams(window.location.search);
window.location.href = 'calendario.html'; if (params.get('sessao') === 'expirada') {
localStorage.removeItem('fa_token');
localStorage.removeItem('fa_user');
const erroEl = document.getElementById('mensagem-erro');
erroEl.textContent = 'Sua sessao expirou. Faca login novamente.';
erroEl.style.display = 'block';
return;
}
const token = localStorage.getItem('fa_token');
if (token && token.split('.').length === 3) {
try {
const payload = JSON.parse(atob(token.split('.')[1]));
if (payload.exp && Date.now() >= payload.exp * 1000) {
localStorage.removeItem('fa_token');
localStorage.removeItem('fa_user');
} else {
window.location.href = 'calendario.html';
return;
}
} catch {
localStorage.removeItem('fa_token');
localStorage.removeItem('fa_user');
}
} else if (token) {
localStorage.removeItem('fa_token');
localStorage.removeItem('fa_user');
} }
})(); })();
@@ -80,13 +107,12 @@
return; return;
} }
// Salva token e dados do usuário
localStorage.setItem('fa_token', json.data.token); localStorage.setItem('fa_token', json.data.token);
localStorage.setItem('fa_user', JSON.stringify(json.data.estudante)); localStorage.setItem('fa_user', JSON.stringify(json.data.estudante));
window.location.href = 'calendario.html'; window.location.href = 'calendario.html';
} catch (err) { } catch (err) {
mostrarErro('Erro de conexão. Verifique se o servidor está rodando.'); mostrarErro('Erro de conexao. Verifique se o servidor esta rodando.');
} finally { } finally {
btn.disabled = false; btn.disabled = false;
btn.textContent = 'Entrar'; btn.textContent = 'Entrar';