You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rz...@apache.org on 2025/06/24 19:11:06 UTC
(tomee) branch jdk24 updated (8c2e610af1 -> ca5eeda9da)
This is an automated email from the ASF dual-hosted git repository.
rzo1 pushed a change to branch jdk24
in repository https://gitbox.apache.org/repos/asf/tomee.git
discard 8c2e610af1 JDK 24 Support?
new ca5eeda9da JDK 24 Support?
This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version. This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:
* -- * -- B -- O -- O -- O (8c2e610af1)
\
N -- N -- N refs/heads/jdk24 (ca5eeda9da)
You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.
Any revisions marked "omit" are not gone; other references still
refer to them. Any revisions marked "discard" are gone forever.
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../core/security/AbstractSecurityService.java | 38 ++++++++++++----------
1 file changed, 21 insertions(+), 17 deletions(-)
(tomee) 01/01: JDK 24 Support?
Posted by rz...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rzo1 pushed a commit to branch jdk24
in repository https://gitbox.apache.org/repos/asf/tomee.git
commit ca5eeda9da5e55c36957a235005e025f0af430eb
Author: Richard Zowalla <rz...@apache.org>
AuthorDate: Tue Jun 24 10:37:06 2025 +0200
JDK 24 Support?
---
.../core/security/AbstractSecurityService.java | 69 +++++++++++------
.../apache/openejb/core/security/PolicyJDK24.java | 46 +++++++++++
.../core/security/jacc/BasicJaccProvider.java | 3 +-
.../openejb/client/JaasIdentityResolver.java | 5 +-
.../apache/openejb/client/util/JDK24Subject.java | 88 ++++++++++++++++++++++
.../java/org/apache/openejb/client/MainTest.java | 5 +-
6 files changed, 190 insertions(+), 26 deletions(-)
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java b/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
index cb56a5f9b7..7c66706d9e 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
@@ -50,6 +50,7 @@ import java.security.Policy;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
@@ -62,6 +63,8 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import static java.util.Arrays.asList;
+import static org.apache.openejb.InterfaceType.BUSINESS_LOCALBEAN_HOME;
+import static org.apache.openejb.InterfaceType.LOCALBEAN;
/**
* This security service chooses a UUID as its token as this can be serialized
@@ -371,24 +374,29 @@ public abstract class AbstractSecurityService implements DestroyableResource, Se
@Override
public boolean isCallerAuthorized(final Method method, final InterfaceType type) {
- final ThreadContext threadContext = ThreadContext.getThreadContext();
- final BeanContext beanContext = threadContext.getBeanContext();
- try {
- final String ejbName = beanContext.getEjbName();
- String name = type == null ? null : type.getSpecName();
- if ("LocalBean".equals(name) || "LocalBeanHome".equals(name)) {
- name = null;
- }
- final Identity currentIdentity = clientIdentity.get();
- final SecurityContext securityContext;
- if (currentIdentity == null) {
- securityContext = threadContext.get(SecurityContext.class);
- } else {
- securityContext = new SecurityContext(currentIdentity.getSubject());
+ if (System.getProperty("java.vm.specification.version").compareTo("24") < 0) {
+ final ThreadContext threadContext = ThreadContext.getThreadContext();
+ final BeanContext beanContext = threadContext.getBeanContext();
+ try {
+
+ final String ejbName = beanContext.getEjbName();
+ String name = type == null ? null : type.getSpecName();
+ if ("LocalBean".equals(name) || "LocalBeanHome".equals(name)) {
+ name = null;
+ }
+
+ final Identity currentIdentity = clientIdentity.get();
+ final SecurityContext securityContext;
+ if (currentIdentity == null) {
+ securityContext = threadContext.get(SecurityContext.class);
+ } else {
+ securityContext = new SecurityContext(currentIdentity.getSubject());
+ }
+
+ securityContext.getAccessControlContext().checkPermission(new EJBMethodPermission(ejbName, name, method));
+ } catch (final AccessControlException e) {
+ return false;
}
- securityContext.getAccessControlContext().checkPermission(new EJBMethodPermission(ejbName, name, method));
- } catch (final AccessControlException e) {
- return false;
}
return true;
}
@@ -422,11 +430,11 @@ public abstract class AbstractSecurityService implements DestroyableResource, Se
// check the system provided provider first - if for some reason it isn't loaded, load it
final String systemPolicyProvider = SystemInstance.get().getOptions().getProperties().getProperty("jakarta.security.jacc.policy.provider");
- if (systemPolicyProvider != null && Policy.getPolicy() == null) {
+ if (systemPolicyProvider != null && getPolicy() == null) {
installPolicy(systemPolicyProvider);
}
- if (! JaccProvider.Policy.class.getName().equals(Policy.getPolicy().getClass().getName())) {
+ if (! JaccProvider.Policy.class.getName().equals(getPolicy().getClass().getName())) {
// this should delegate to the policy installed above
installPolicy(JaccProvider.Policy.class.getName());
}
@@ -436,15 +444,34 @@ public abstract class AbstractSecurityService implements DestroyableResource, Se
try {
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
final Class policyClass = Class.forName(policyProvider, true, classLoader);
- final Policy policy = (Policy) policyClass.newInstance();
+ final Policy policy = (Policy) policyClass.getDeclaredConstructor().newInstance();
policy.refresh();
- Policy.setPolicy(policy);
+ setPolicy(policy);
} catch (final Exception e) {
throw new IllegalStateException("Could not install JACC Policy Provider: " + policyProvider, e);
}
}
+ public static Policy getPolicy() {
+ Policy policy = PolicyJDK24.getPolicy();
+ if (policy == null) {
+ policy = Policy.getPolicy();
+ }
+
+ return policy;
+ }
+
+ public static void setPolicy(Policy policy) {
+ try {
+ Policy.setPolicy(policy);
+ } catch (UnsupportedOperationException e) {
+ //we are running JDK 24 or later, so no system-wide policy possible.
+ PolicyJDK24.setPolicy(policy);
+ }
+ }
+
+
protected Subject createSubject(final String name, final String groupName) {
if (name == null) {
return null;
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/security/PolicyJDK24.java b/container/openejb-core/src/main/java/org/apache/openejb/core/security/PolicyJDK24.java
new file mode 100644
index 0000000000..6db9ccf4cb
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/security/PolicyJDK24.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.core.security;
+
+import java.security.Policy;
+
+/**
+ * A utility class to manage the Java Security Policy in a thread-safe manner.
+ * This class provides methods to get and set the security policy, ensuring
+ * that changes are synchronized across threads.
+ */
+public class PolicyJDK24 {
+
+ private static volatile Policy policy;
+
+ /**
+ * @return the policy
+ */
+ public static synchronized Policy getPolicy() {
+ return policy;
+ }
+
+ /**
+ * @param policy the policy to set
+ */
+ public static synchronized void setPolicy(Policy policy) {
+ PolicyJDK24.policy = policy;
+ }
+
+
+
+}
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/security/jacc/BasicJaccProvider.java b/container/openejb-core/src/main/java/org/apache/openejb/core/security/jacc/BasicJaccProvider.java
index 3db5c4af63..6a2f77811b 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/security/jacc/BasicJaccProvider.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/security/jacc/BasicJaccProvider.java
@@ -18,6 +18,7 @@
package org.apache.openejb.core.security.jacc;
import org.apache.openejb.core.security.JaccProvider;
+import org.apache.openejb.core.security.PolicyJDK24;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.spi.SecurityService;
@@ -66,7 +67,7 @@ public class BasicJaccProvider extends JaccProvider {
private final java.security.Policy systemPolicy;
public BasicJaccProvider() {
- systemPolicy = Policy.getPolicy();
+ systemPolicy = PolicyJDK24.getPolicy();
}
public PolicyConfiguration getPolicyConfiguration(final String contextID, final boolean remove) throws PolicyContextException {
diff --git a/server/openejb-client/src/main/java/org/apache/openejb/client/JaasIdentityResolver.java b/server/openejb-client/src/main/java/org/apache/openejb/client/JaasIdentityResolver.java
index 2193d03aaa..26fcf5cfd4 100644
--- a/server/openejb-client/src/main/java/org/apache/openejb/client/JaasIdentityResolver.java
+++ b/server/openejb-client/src/main/java/org/apache/openejb/client/JaasIdentityResolver.java
@@ -17,15 +17,16 @@
*/
package org.apache.openejb.client;
+import org.apache.openejb.client.util.JDK24Subject;
+
import javax.security.auth.Subject;
-import java.security.AccessController;
import java.util.Set;
public class JaasIdentityResolver implements IdentityResolver {
@Override
public Object getIdentity() {
- final Subject subject = Subject.getSubject(AccessController.getContext());
+ final Subject subject = JDK24Subject.currentSubject();
if (subject == null) {
return null;
}
diff --git a/server/openejb-client/src/main/java/org/apache/openejb/client/util/JDK24Subject.java b/server/openejb-client/src/main/java/org/apache/openejb/client/util/JDK24Subject.java
new file mode 100644
index 0000000000..3b35ff8d87
--- /dev/null
+++ b/server/openejb-client/src/main/java/org/apache/openejb/client/util/JDK24Subject.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.client.util;
+
+import javax.security.auth.Subject;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
+public class JDK24Subject {
+
+ private static final MethodHandle CURRENT = lookupCurrent();
+
+ /**
+ * Maps to Subject.current() 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);
+ }
+ }
+}
diff --git a/server/openejb-client/src/test/java/org/apache/openejb/client/MainTest.java b/server/openejb-client/src/test/java/org/apache/openejb/client/MainTest.java
index ea10f2e667..380407a481 100644
--- a/server/openejb-client/src/test/java/org/apache/openejb/client/MainTest.java
+++ b/server/openejb-client/src/test/java/org/apache/openejb/client/MainTest.java
@@ -18,6 +18,7 @@
package org.apache.openejb.client;
import junit.framework.TestCase;
+import org.apache.openejb.client.util.JDK24Subject;
import javax.naming.Binding;
import javax.naming.Context;
@@ -87,7 +88,7 @@ public class MainTest extends TestCase {
public static class SecureMain {
public static void main(String[] args) {
- Subject subject = Subject.getSubject(AccessController.getContext());
+ Subject subject = JDK24Subject.currentSubject();
// verify subject
assertEquals("Should have one principal", 1, subject.getPrincipals().size());
@@ -109,7 +110,7 @@ public class MainTest extends TestCase {
public static class NormalMain {
public static void main(String[] args) {
- Subject subject = Subject.getSubject(AccessController.getContext());
+ Subject subject = JDK24Subject.currentSubject();
assertNull("subject is not null", subject);