Skip to content

Commit 9c3f7d8

Browse files
committed
update CORS filter
1 parent ba7df0e commit 9c3f7d8

File tree

4 files changed

+115
-19
lines changed

4 files changed

+115
-19
lines changed

.idea/dataSources.xml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/data_source_mapping.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 95 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,118 @@
11
package fr.github.vera.filters;
22

3+
import fr.github.vera.config.ConfigProperties;
34
import jakarta.ws.rs.container.*;
45
import jakarta.ws.rs.core.Response;
56
import jakarta.ws.rs.ext.Provider;
67

78
import java.io.IOException;
9+
import java.lang.reflect.Method;
810

911
@Provider
1012
@PreMatching
1113
public class CorsFilter implements ContainerRequestFilter, ContainerResponseFilter {
14+
private boolean isPublicEndpoint(ContainerRequestContext requestContext) {
15+
try {
16+
// Récupérer la méthode de la ressource depuis le contexte
17+
Object resourceMethodInvoker = requestContext
18+
.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker");
19+
20+
if (resourceMethodInvoker != null) {
21+
// Utiliser la réflexion pour accéder à la méthode
22+
Method getMethod = resourceMethodInvoker.getClass().getMethod("getMethod");
23+
Method resourceMethod = (Method) getMethod.invoke(resourceMethodInvoker);
24+
25+
// Vérifier si la méthode ou sa classe a l'annotation @Public
26+
return resourceMethod.isAnnotationPresent(Public.class) ||
27+
resourceMethod.getDeclaringClass().isAnnotationPresent(Public.class);
28+
}
29+
} catch (Exception e) {
30+
return false;
31+
}
32+
return false;
33+
}
34+
1235

1336
@Override
1437
public void filter(ContainerRequestContext requestContext,
1538
ContainerResponseContext responseContext) {
16-
// Accepter toutes les origines
17-
responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
18-
responseContext.getHeaders().add("Access-Control-Allow-Headers",
19-
"origin, content-type, accept, authorization, x-requested-with");
20-
// NE PAS mettre credentials à true quand origin est "*"
21-
responseContext.getHeaders().add("Access-Control-Allow-Methods",
22-
"GET, POST, PUT, DELETE, OPTIONS, HEAD");
23-
responseContext.getHeaders().add("Access-Control-Max-Age", "3600");
39+
40+
String origin = requestContext.getHeaderString("Origin");
41+
boolean isPublic = isPublicEndpoint(requestContext);
42+
43+
setCorsHeaders(responseContext, origin, isPublic);
2444
}
2545

2646
@Override
2747
public void filter(ContainerRequestContext requestContext) throws IOException {
28-
// Gérer les requêtes OPTIONS (preflight)
48+
2949
if ("OPTIONS".equals(requestContext.getMethod())) {
30-
Response response = Response.ok()
31-
.header("Access-Control-Allow-Origin", "*")
32-
.header("Access-Control-Allow-Headers",
33-
"origin, content-type, accept, authorization, x-requested-with")
34-
.header("Access-Control-Allow-Methods",
35-
"GET, POST, PUT, DELETE, OPTIONS, HEAD")
36-
.header("Access-Control-Max-Age", "3600")
37-
.build();
38-
requestContext.abortWith(response);
50+
// Pour les requêtes preflight, on doit déterminer si le chemin est public
51+
boolean isPublic = isPublicEndpoint(requestContext);
52+
String origin = requestContext.getHeaderString("Origin");
53+
54+
Response.ResponseBuilder responseBuilder = Response.ok();
55+
setCorsHeaders(responseBuilder, origin, isPublic);
56+
requestContext.abortWith(responseBuilder.build());
57+
}
58+
}
59+
60+
private void setCorsHeaders(ContainerResponseContext responseContext,
61+
String origin, boolean isPublic) {
62+
63+
if (isPublic) {
64+
// Endpoint public : toutes origines autorisées
65+
responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
66+
} else {
67+
// Endpoint protégé : seulement les domaines autorisés
68+
if (origin != null && isOriginAllowed(origin)) {
69+
responseContext.getHeaders().add("Access-Control-Allow-Origin", origin);
70+
responseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
71+
}
72+
}
73+
74+
// Headers communs
75+
responseContext.getHeaders().add("Access-Control-Allow-Headers",
76+
"origin, content-type, accept, authorization, x-requested-with, x-csrf-token");
77+
responseContext.getHeaders().add("Access-Control-Allow-Methods",
78+
"GET, POST, PUT, DELETE, OPTIONS, HEAD, PATCH");
79+
responseContext.getHeaders().add("Access-Control-Max-Age", "3600");
80+
responseContext.getHeaders().add("Access-Control-Expose-Headers",
81+
"x-csrf-token, authorization");
82+
}
83+
84+
private void setCorsHeaders(Response.ResponseBuilder responseBuilder,
85+
String origin, boolean isPublic) {
86+
87+
if (isPublic) {
88+
responseBuilder.header("Access-Control-Allow-Origin", "*");
89+
} else if (origin != null && isOriginAllowed(origin)) {
90+
responseBuilder.header("Access-Control-Allow-Origin", origin);
91+
responseBuilder.header("Access-Control-Allow-Credentials", "true");
92+
}
93+
94+
// Headers communs
95+
responseBuilder.header("Access-Control-Allow-Headers",
96+
"origin, content-type, accept, authorization, x-requested-with, x-csrf-token");
97+
responseBuilder.header("Access-Control-Allow-Methods",
98+
"GET, POST, PUT, DELETE, OPTIONS, HEAD, PATCH");
99+
responseBuilder.header("Access-Control-Max-Age", "3600");
100+
}
101+
102+
private boolean isOriginAllowed(String origin) {
103+
// Support multiple domains
104+
String allowedDomain = ConfigProperties.getInstance().getProperty("cors.allowed-domain");
105+
String[] domains = allowedDomain.split(",");
106+
for (String domain : domains) {
107+
String trimmed = domain.trim();
108+
if (origin.equals(trimmed)) {
109+
return true;
110+
}
111+
// Support pour localhost avec différents ports
112+
if (trimmed.startsWith("http://localhost") && origin.startsWith("http://localhost")) {
113+
return true;
114+
}
39115
}
116+
return false;
40117
}
41118
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
secret=${SECRET;Vahgtjj8PN2cFjtEfxkm6QvIid4acyrGPB+N60dG6Wo5l9Rd7Wjnc+OnIokMoyoWh++YJZKzg1CsE2fabQ+Hlc1JEB09FBua}
1+
secret=${SECRET;Vahgtjj8PN2cFjtEfxkm6QvIid4acyrGPB+N60dG6Wo5l9Rd7Wjnc+OnIokMoyoWh++YJZKzg1CsE2fabQ+Hlc1JEB09FBua}
2+
cors.allowed-domain=${CORS_ALLOWED_DOMAIN;http://localhost}

0 commit comments

Comments
 (0)