Commit 44b36fff by Rubén Ramírez

fix: [*]: Corregido problema con la expiración de tokens y tokens inválidos

parent 3c7dca7a
package com.ujaen.tfg.mangaffinity.excepciones;
public class TokenExpirado extends RuntimeException {
}
package com.ujaen.tfg.mangaffinity.excepciones;
public class TokenInvalido extends RuntimeException {
}
package com.ujaen.tfg.mangaffinity.seguridad;
import com.ujaen.tfg.mangaffinity.excepciones.TokenExpirado;
import com.ujaen.tfg.mangaffinity.excepciones.TokenInvalido;
import io.jsonwebtoken.Claims;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.Collections;
public class JwtFilter extends OncePerRequestFilter {
private final JwtUtil jwtUtil;
public JwtFilter(JwtUtil jwtUtil) {
this.jwtUtil = jwtUtil;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
String token = request.getHeader("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
chain.doFilter(request, response); // Continúa sin forzar autenticación
return;
}
token = token.substring(7); // Removemos "Bearer "
try {
Claims claims = jwtUtil.decodeJWT(token);
request.setAttribute("claims", claims);
// Crear objeto de autenticación en Spring Security
User userDetails = new User(claims.getSubject(), "", Collections.emptyList());
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// Establecer autenticación en el contexto de seguridad
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (TokenExpirado e) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("El token ha expirado.");
return;
} catch (TokenInvalido e) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("Token inválido.");
return;
}
chain.doFilter(request, response);
}
}
package com.ujaen.tfg.mangaffinity.seguridad; package com.ujaen.tfg.mangaffinity.seguridad;
import com.ujaen.tfg.mangaffinity.excepciones.TokenExpirado;
import com.ujaen.tfg.mangaffinity.excepciones.TokenInvalido;
import io.jsonwebtoken.*; import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys; import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
...@@ -28,13 +30,20 @@ public class JwtUtil { ...@@ -28,13 +30,20 @@ public class JwtUtil {
// Decodifica el JWT // Decodifica el JWT
public Claims decodeJWT(String token) { public Claims decodeJWT(String token) {
return Jwts.parserBuilder() try {
.setSigningKey(SECRET_KEY) // Usamos la misma clave para decodificar return Jwts.parserBuilder()
.build() .setSigningKey(SECRET_KEY)
.parseClaimsJws(token) .build()
.getBody(); .parseClaimsJws(token)
.getBody();
} catch (ExpiredJwtException e) {
throw new TokenExpirado();
} catch (MalformedJwtException | SignatureException | IllegalArgumentException e) {
throw new TokenInvalido();
}
} }
// Extrae el nombre de usuario // Extrae el nombre de usuario
public String extractUsername(String token) { public String extractUsername(String token) {
return extractClaim(token, Claims::getSubject); return extractClaim(token, Claims::getSubject);
......
...@@ -8,12 +8,19 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe ...@@ -8,12 +8,19 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
public class ServicioSeguridad { public class ServicioSeguridad {
private final JwtUtil jwtUtil;
public ServicioSeguridad(JwtUtil jwtUtil) {
this.jwtUtil = jwtUtil;
}
@Bean @Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
...@@ -24,7 +31,9 @@ public class ServicioSeguridad { ...@@ -24,7 +31,9 @@ public class ServicioSeguridad {
.authorizeHttpRequests(request -> request .authorizeHttpRequests(request -> request
.requestMatchers(HttpMethod.POST, "/usuarios/{email}").permitAll() .requestMatchers(HttpMethod.POST, "/usuarios/{email}").permitAll()
.requestMatchers(HttpMethod.POST, "/usuarios/").permitAll() .requestMatchers(HttpMethod.POST, "/usuarios/").permitAll()
.anyRequest().authenticated()
) )
.addFilterBefore(new JwtFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class)
.build(); .build();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment