22
33import jakarta .annotation .Priority ;
44import jakarta .ws .rs .Priorities ;
5- import jakarta .ws .rs .container .ContainerRequestContext ;
6- import jakarta .ws .rs .container .ContainerRequestFilter ;
7- import jakarta .ws .rs .container .ContainerResponseContext ;
8- import jakarta .ws .rs .container .ContainerResponseFilter ;
5+ import jakarta .ws .rs .container .*;
6+ import jakarta .ws .rs .core .Context ;
97import jakarta .ws .rs .core .Response ;
108import jakarta .ws .rs .ext .Provider ;
119import org .apache .logging .log4j .LogManager ;
1210import org .apache .logging .log4j .Logger ;
1311
1412import java .io .IOException ;
13+ import java .lang .reflect .Method ;
1514import java .security .SecureRandom ;
1615import java .util .Base64 ;
1716import java .util .Map ;
@@ -25,33 +24,23 @@ public class CsrfFilter implements ContainerRequestFilter, ContainerResponseFilt
2524 private static final String CSRF_TOKEN_HEADER = "X-CSRF-Token" ;
2625 private static final String CLIENT_TYPE_HEADER = "X-Client-Type" ;
2726 private static final String WEB_CLIENT = "web" ;
28-
29- // Stockage en mémoire (session utilisateur -> token)
3027 private static final Map <String , String > tokenStore = new ConcurrentHashMap <>();
3128
29+
30+ @ Context
31+ private ResourceInfo resourceInfo ;
32+
3233 @ Override
3334 public void filter (ContainerRequestContext requestContext ) throws IOException {
3435 String method = requestContext .getMethod ();
3536 String path = requestContext .getUriInfo ().getPath ();
3637
37- // Méthodes sûres : pas besoin de vérifier CSRF
38- if ("GET" .equals (method ) || "HEAD" .equals (method ) || "OPTIONS" .equals (method )) {
39- return ;
40- }
41-
42- // Endpoints publics - pas de CSRF
43- if (path .startsWith ("auth/login" ) ||
44- path .startsWith ("auth/register" ) ||
45- path .startsWith ("auth/refresh" ) ||
46- path .startsWith ("auth/forgot-password" ) ||
47- path .startsWith ("auth/reset-password" ) ||
48- path .equals ("health" )) {
38+ if ("GET" .equals (method ) || "HEAD" .equals (method ) || "OPTIONS" .equals (method ) || isPublicEndpoint ()) {
4939 return ;
5040 }
5141
52- // 🔥 Vérifier si c'est un client web
5342 if (!isWebClient (requestContext )) {
54- logger .debug ("Client API (Postman) - skip CSRF pour {} {}" , method , path );
43+ logger .debug ("Client API - non web - skip CSRF pour {} {}" , method , path );
5544 return ;
5645 }
5746
@@ -62,7 +51,6 @@ public void filter(ContainerRequestContext requestContext) throws IOException {
6251 return ;
6352 }
6453
65- // Vérifier le token CSRF
6654 String csrfToken = requestContext .getHeaderString (CSRF_TOKEN_HEADER );
6755 String storedToken = tokenStore .get (sessionId );
6856
@@ -79,8 +67,6 @@ public void filter(ContainerRequestContext requestContext) throws IOException {
7967 @ Override
8068 public void filter (ContainerRequestContext requestContext ,
8169 ContainerResponseContext responseContext ) throws IOException {
82-
83- // 🔥 Générer token CSRF SEULEMENT pour les clients web
8470 if ("GET" .equals (requestContext .getMethod ()) && isWebClient (requestContext )) {
8571 String sessionId = getSessionId (requestContext );
8672 if (sessionId != null ) {
@@ -99,7 +85,6 @@ private boolean isWebClient(ContainerRequestContext requestContext) {
9985 }
10086
10187 private String getSessionId (ContainerRequestContext request ) {
102- // Utiliser le token JWT comme session ID
10388 String authHeader = request .getHeaderString ("Authorization" );
10489 if (authHeader != null && authHeader .startsWith ("Bearer " )) {
10590 String jwtToken = authHeader .substring (7 );
@@ -114,4 +99,13 @@ private String generateToken() {
11499 random .nextBytes (bytes );
115100 return Base64 .getUrlEncoder ().withoutPadding ().encodeToString (bytes );
116101 }
102+
103+ private boolean isPublicEndpoint () {
104+ Method method = resourceInfo .getResourceMethod ();
105+ Class <?> resourceClass = resourceInfo .getResourceClass ();
106+ if (method != null && method .isAnnotationPresent (Public .class )) {
107+ return true ;
108+ }
109+ return resourceClass != null && resourceClass .isAnnotationPresent (Public .class );
110+ }
117111}
0 commit comments