From 74c923088203efb7f608774a61d13ea1d70449eb Mon Sep 17 00:00:00 2001 From: Richard Zowalla Date: Sun, 23 Feb 2025 17:00:50 +0100 Subject: [PATCH 1/2] #7935 - Use reflection to handle Java SecurityManager deprecation --- .../storm/security/auth/ReqContext.java | 76 +++++++++++++++++-- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/storm-client/src/jvm/org/apache/storm/security/auth/ReqContext.java b/storm-client/src/jvm/org/apache/storm/security/auth/ReqContext.java index 11a1cdf2d5f..c591f963291 100644 --- a/storm-client/src/jvm/org/apache/storm/security/auth/ReqContext.java +++ b/storm-client/src/jvm/org/apache/storm/security/auth/ReqContext.java @@ -18,9 +18,10 @@ package org.apache.storm.security.auth; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.net.InetAddress; -import java.security.AccessControlContext; -import java.security.AccessController; import java.security.Principal; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; @@ -36,10 +37,13 @@ * */ public class ReqContext { + + private static final MethodHandle CURRENT = lookupCurrent(); + private static final AtomicInteger uniqueId = new AtomicInteger(0); //each thread will have its own request context private static final ThreadLocal ctxt = - ThreadLocal.withInitial(() -> new ReqContext(AccessController.getContext())); + ThreadLocal.withInitial(ReqContext::new); private Subject subject; private InetAddress remoteAddr; private final int reqId; @@ -47,8 +51,8 @@ public class ReqContext { //private constructor @VisibleForTesting - public ReqContext(AccessControlContext aclCtxt) { - subject = Subject.getSubject(aclCtxt); + public ReqContext() { + subject = currentSubject(); reqId = uniqueId.incrementAndGet(); } @@ -161,4 +165,66 @@ public boolean isImpersonating() { public int requestID() { return reqId; } + + /** + * Maps to Subject.currect() is available, otherwise maps to Subject.getSubject() + * @return the current subject + */ + public static Subject currentSubject() { + try { + return (Subject) CURRENT.invoke(); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + private static MethodHandle lookupCurrent() { + final MethodHandles.Lookup lookup = MethodHandles.lookup(); + try { + // Subject.getSubject(AccessControlContext) is deprecated for removal and replaced by + // Subject.current(). + // Lookup first the new API, since for Java versions where both exists, the + // new API delegates to the old API (for example Java 18, 19 and 20). + // Otherwise (Java 17), lookup the old API. + return lookup.findStatic(Subject.class, "current", + MethodType.methodType(Subject.class)); + } catch (NoSuchMethodException e) { + final MethodHandle getContext = lookupGetContext(); + final MethodHandle getSubject = lookupGetSubject(); + return MethodHandles.filterReturnValue(getContext, getSubject); + } catch (IllegalAccessException e) { + throw new AssertionError(e); + } + } + + private static MethodHandle lookupGetSubject() { + final MethodHandles.Lookup lookup = MethodHandles.lookup(); + try { + final Class contextClazz = + ClassLoader.getSystemClassLoader() + .loadClass("java.security.AccessControlContext"); + return lookup.findStatic(Subject.class, "getSubject", + MethodType.methodType(Subject.class, contextClazz)); + } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) { + throw new AssertionError(e); + } + } + + private static MethodHandle lookupGetContext() { + try { + // Use reflection to work with Java versions that have and don't have AccessController. + final Class controllerClazz = + ClassLoader.getSystemClassLoader().loadClass("java.security.AccessController"); + final Class contextClazz = + ClassLoader.getSystemClassLoader() + .loadClass("java.security.AccessControlContext"); + + MethodHandles.Lookup lookup = MethodHandles.lookup(); + return lookup.findStatic(controllerClazz, "getContext", + MethodType.methodType(contextClazz)); + } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) { + throw new AssertionError(e); + } + } + } From 775be94e241d907f2cb966b15dd035fe98f3ce41 Mon Sep 17 00:00:00 2001 From: Richard Zowalla Date: Mon, 3 Mar 2025 09:01:48 +0100 Subject: [PATCH 2/2] Fix typo --- .../src/jvm/org/apache/storm/security/auth/ReqContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storm-client/src/jvm/org/apache/storm/security/auth/ReqContext.java b/storm-client/src/jvm/org/apache/storm/security/auth/ReqContext.java index c591f963291..830165084f5 100644 --- a/storm-client/src/jvm/org/apache/storm/security/auth/ReqContext.java +++ b/storm-client/src/jvm/org/apache/storm/security/auth/ReqContext.java @@ -167,7 +167,7 @@ public int requestID() { } /** - * Maps to Subject.currect() is available, otherwise maps to Subject.getSubject() + * Maps to Subject.current() is available, otherwise maps to Subject.getSubject() * @return the current subject */ public static Subject currentSubject() {