Skip to content

Commit 713d88d

Browse files
committed
refact: enhance auth logic
fix
1 parent ef8f612 commit 713d88d

File tree

11 files changed

+201
-152
lines changed

11 files changed

+201
-152
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ achieved through [Gremlin](https://tinkerpop.apache.org/gremlin.html)(a powerful
3636

3737
We can use `docker run -itd --name=graph -p 8080:8080 hugegraph/hugegraph` to quickly start an inner
3838
HugeGraph server with `RocksDB` (in backgrounds) for **test/dev**.
39-
You can visit [doc page](https://hugegraph.apache.org/docs/quickstart/hugegraph-server/#3-deploy) or the [README](hugegraph-server/hugegraph-dist/docker/READEME.md) for more details.
39+
You can visit [doc page](https://hugegraph.apache.org/docs/quickstart/hugegraph-server/#3-deploy) or
40+
the [README](hugegraph-server/hugegraph-dist/docker/READEME.md) for more details. ([Docker Compose](./hugegraph-server/hugegraph-dist/docker/example))
4041

4142
> Note:
4243
>
@@ -58,12 +59,11 @@ The project [doc page](https://hugegraph.apache.org/docs/) contains more informa
5859
and provides detailed documentation for users. (Structure / Usage / API / Configs...)
5960

6061
And here are links of other **HugeGraph** component/repositories:
61-
1. [hugegraph-toolchain](https://github.com/apache/incubator-hugegraph-toolchain) (graph tools **[loader](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-loader)/[dashboard](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-hubble)/[tool](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-tools)/[client](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-client)**)
62-
2. [hugegraph-computer](https://github.com/apache/incubator-hugegraph-computer) (integrated **graph computing** system)
63-
3. [hugegraph-commons](https://github.com/apache/incubator-hugegraph-commons) (**common & rpc** libs)
64-
4. [hugegraph-website](https://github.com/apache/incubator-hugegraph-doc) (**doc & website** code)
65-
66-
62+
1. [hugegraph-toolchain](https://github.com/apache/hugegraph-toolchain) (graph tools **[loader](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-loader)/[dashboard](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-hubble)/[tool](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-tools)/[client](https://github.com/apache/incubator-hugegraph-toolchain/tree/master/hugegraph-client)**)
63+
2. [hugegraph-computer](https://github.com/apache/hugegraph-computer) (integrated **graph computing** system)
64+
3. [hugegraph-commons](https://github.com/apache/hugegraph-commons) (**common & rpc** libs)
65+
4. [hugegraph-website](https://github.com/apache/hugegraph-doc) (**doc & website** code)
66+
5. [hugegraph-ai](https://github.com/apache/incubator-hugegraph-ai) (integrated **Graph AI/LLM/KG** system)
6767

6868
## License
6969

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/auth/LoginAPI.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ public String login(@Context GraphManager manager, @PathParam("graph") String gr
8484
@Status(Status.OK)
8585
@Consumes(APPLICATION_JSON)
8686
@Produces(APPLICATION_JSON_WITH_CHARSET)
87-
public void logout(@Context GraphManager manager,
88-
@PathParam("graph") String graph,
87+
public void logout(@Context GraphManager manager, @PathParam("graph") String graph,
8988
@HeaderParam(HttpHeaders.AUTHORIZATION) String auth) {
9089
E.checkArgument(StringUtils.isNotEmpty(auth),
9190
"Request header Authorization must not be null");
@@ -105,10 +104,8 @@ public void logout(@Context GraphManager manager,
105104
@Status(Status.OK)
106105
@Consumes(APPLICATION_JSON)
107106
@Produces(APPLICATION_JSON_WITH_CHARSET)
108-
public String verifyToken(@Context GraphManager manager,
109-
@PathParam("graph") String graph,
110-
@HeaderParam(HttpHeaders.AUTHORIZATION)
111-
String token) {
107+
public String verifyToken(@Context GraphManager manager, @PathParam("graph") String graph,
108+
@HeaderParam(HttpHeaders.AUTHORIZATION) String token) {
112109
E.checkArgument(StringUtils.isNotEmpty(token),
113110
"Request header Authorization must not be null");
114111
LOG.debug("Graph [{}] get user: {}", graph, token);

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/AuthenticationFilter.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,7 @@ private boolean matchPermission(String required) {
259259

260260
if (LOG.isDebugEnabled()) {
261261
LOG.debug("Verify permission {} {} for user '{}' with role {}",
262-
requiredPerm.action().string(),
263-
requiredPerm.resourceObject(),
262+
requiredPerm.action().string(), requiredPerm.resourceObject(),
264263
this.user.username(), this.user.role());
265264
}
266265

@@ -269,9 +268,8 @@ private boolean matchPermission(String required) {
269268

270269
if (!valid && LOG.isInfoEnabled() &&
271270
!required.equals(HugeAuthenticator.USER_ADMIN)) {
272-
LOG.info("User '{}' is denied to {} {}",
273-
this.user.username(), requiredPerm.action().string(),
274-
requiredPerm.resourceObject());
271+
LOG.info("User '{}' is denied to {} {}", this.user.username(),
272+
requiredPerm.action().string(), requiredPerm.resourceObject());
275273
}
276274
return valid;
277275
}

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/gremlin/GremlinQueryAPI.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@
3737
public class GremlinQueryAPI extends API {
3838

3939
private static final Set<String> FORBIDDEN_REQUEST_EXCEPTIONS =
40-
ImmutableSet.of("java.lang.SecurityException",
41-
"jakarta.ws.rs.ForbiddenException");
40+
ImmutableSet.of("java.lang.SecurityException", "jakarta.ws.rs.ForbiddenException");
4241
private static final Set<String> BAD_REQUEST_EXCEPTIONS = ImmutableSet.of(
4342
"java.lang.IllegalArgumentException",
4443
"java.util.concurrent.TimeoutException",
@@ -56,6 +55,7 @@ public GremlinClient client() {
5655
if (this.client != null) {
5756
return this.client;
5857
}
58+
5959
HugeConfig config = this.configProvider.get();
6060
String url = config.get(ServerOptions.GREMLIN_SERVER_URL);
6161
int timeout = config.get(ServerOptions.GREMLIN_SERVER_TIMEOUT) * 1000;
@@ -100,6 +100,7 @@ private static boolean matchBadRequestException(String exClass) {
100100
if (exClass == null) {
101101
return false;
102102
}
103+
103104
if (BAD_REQUEST_EXCEPTIONS.contains(exClass)) {
104105
return true;
105106
}

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/auth/HugeFactoryAuthProxy.java

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,16 @@
5757
import org.apache.hugegraph.traversal.optimize.HugeCountStepStrategy;
5858
import org.apache.hugegraph.traversal.optimize.HugeGraphStepStrategy;
5959
import org.apache.hugegraph.traversal.optimize.HugeVertexStepStrategy;
60+
import org.apache.hugegraph.util.Log;
6061
import org.apache.hugegraph.util.Reflection;
6162
import org.apache.hugegraph.variables.HugeVariables;
63+
import org.slf4j.Logger;
6264

6365
import com.google.common.collect.ImmutableSet;
6466

6567
public final class HugeFactoryAuthProxy {
6668

69+
private static final Logger LOG = Log.logger(HugeFactoryAuthProxy.class);
6770
public static final String GRAPH_FACTORY =
6871
"gremlin.graph=org.apache.hugegraph.auth.HugeFactoryAuthProxy";
6972

@@ -90,7 +93,11 @@ public static synchronized HugeGraph open(Configuration config) {
9093
return proxy;
9194
}
9295

96+
// TODO: add some test to ensure the effect & partially move to HugeSecurityManager
9397
private static void registerPrivateActions() {
98+
// Sensitive classes (Be careful to add classes here due to JDK compatibility)
99+
filterCriticalSystemClasses();
100+
94101
// Thread
95102
Reflection.registerFieldsToFilter(java.lang.Thread.class, "name", "priority", "threadQ",
96103
"eetop", "single_step", "daemon", "stillborn", "target",
@@ -106,7 +113,7 @@ private static void registerPrivateActions() {
106113
"threadLocalRandomSecondarySeed");
107114
Reflection.registerMethodsToFilter(java.lang.Thread.class, "exit",
108115
"dispatchUncaughtException", "clone", "isInterrupted",
109-
"registerNatives", "init", "init", "nextThreadNum",
116+
"registerNatives", "init", "nextThreadNum",
110117
"nextThreadID", "blockedOn", "start0", "isCCLOverridden",
111118
"auditSubclass", "dumpThreads", "getThreads",
112119
"processQueue", "setPriority0", "stop0", "suspend0",
@@ -477,6 +484,26 @@ private static void registerPrivateActions() {
477484
//genRegisterPrivateActions();
478485
}
479486

487+
public static void filterCriticalSystemClasses() {
488+
// TODO: merge them in HugeSecurityManager after 1.5.0
489+
Reflection.registerMethodsToFilter(Class.class, "forName", "newInstance");
490+
Reflection.registerMethodsToFilter(ClassLoader.class, "loadClass", "newInstance");
491+
Reflection.registerMethodsToFilter(Method.class, "invoke", "setAccessible");
492+
Reflection.registerMethodsToFilter(Field.class, "set", "setAccessible");
493+
Reflection.registerMethodsToFilter(java.lang.reflect.Constructor.class, "newInstance",
494+
"setAccessible");
495+
Reflection.registerMethodsToFilter(Runtime.class, "exec", "getRuntime");
496+
Reflection.registerMethodsToFilter(ProcessBuilder.class, "command", "start",
497+
"startPipeline");
498+
Reflection.registerMethodsToFilter(loadClass("java.lang.ProcessImpl"), "forkAndExec",
499+
"setAccessible", "start");
500+
501+
optionalMethodsToFilter("sun.invoke.util.BytecodeDescriptor", "parseMethod", "parseSig");
502+
optionalMethodsToFilter("sun.reflect.misc.MethodUtil", "invoke");
503+
optionalMethodsToFilter("jdk.internal.reflect.MethodAccessor", "invoke");
504+
optionalMethodsToFilter("jdk.internal.reflect.NativeMethodAccessorImpl", "invoke");
505+
}
506+
480507
@SuppressWarnings("unused")
481508
private static void genRegisterPrivateActions() {
482509
registerPrivateActions(Thread.class);
@@ -562,20 +589,18 @@ private static void registerPrivateActions(Class<?> clazz) {
562589
}
563590
}
564591

565-
private static boolean registerClass(Class<?> clazz,
566-
List<String> fields,
567-
List<String> methods) {
568-
if (clazz.getName().startsWith("java") ||
569-
fields.isEmpty() && methods.isEmpty()) {
570-
return false;
592+
private static void registerClass(Class<?> clazz, List<String> fields, List<String> methods) {
593+
if (clazz.getName().startsWith("java") || fields.isEmpty() && methods.isEmpty()) {
594+
return;
571595
}
596+
572597
final String[] array = new String[fields.size()];
573598
try {
574599
Reflection.registerFieldsToFilter(clazz, fields.toArray(array));
575600
Reflection.registerMethodsToFilter(clazz, methods.toArray(array));
576601
} catch (IllegalArgumentException e) {
577602
if (e.getMessage().contains("Filter already registered: class")) {
578-
return false;
603+
return;
579604
}
580605
throw e;
581606
}
@@ -596,8 +621,6 @@ private static boolean registerClass(Class<?> clazz,
596621
System.out.println(code);
597622
// CHECKSTYLE:ON
598623
}
599-
600-
return true;
601624
}
602625

603626
private static Class<?> loadClass(String clazz) {
@@ -607,4 +630,17 @@ private static Class<?> loadClass(String clazz) {
607630
throw new HugeException(e.getMessage(), e);
608631
}
609632
}
633+
634+
public static void optionalMethodsToFilter(String className, String... methodNames) {
635+
Class<?> clazz = null;
636+
try {
637+
clazz = Class.forName(className);
638+
} catch (ClassNotFoundException e) {
639+
// TODO: we just ignore the exception, change it after we drop Java8 support
640+
LOG.warn("Skip register class {} to filter", className);
641+
}
642+
if (clazz != null) {
643+
Reflection.registerMethodsToFilter(clazz, methodNames);
644+
}
645+
}
610646
}

0 commit comments

Comments
 (0)