Remove usage of a SecurityManager from EE11 (#12032)
Use callAs rather than doAs Disable after java 21
This commit is contained in:
parent
b0b204cb35
commit
12db285f17
|
@ -214,7 +214,7 @@ public class SPNEGOAuthentication extends AbstractAuthentication
|
|||
|
||||
String b64Input = headerInfo.getBase64();
|
||||
byte[] input = b64Input == null ? new byte[0] : Base64.getDecoder().decode(b64Input);
|
||||
byte[] output = SecurityUtils.doAs(spnegoContext.subject, initGSSContext(spnegoContext, request.getHost(), input));
|
||||
byte[] output = SecurityUtils.callAs(spnegoContext.subject, initGSSContext(spnegoContext, request.getHost(), input));
|
||||
String b64Output = output == null ? null : new String(Base64.getEncoder().encode(output));
|
||||
|
||||
// The result cannot be used for subsequent requests,
|
||||
|
|
|
@ -143,7 +143,7 @@ public class SPNEGOLoginService extends ContainerLifeCycle implements LoginServi
|
|||
LoginContext loginContext = new LoginContext("", null, null, new SPNEGOConfiguration());
|
||||
loginContext.login();
|
||||
Subject subject = loginContext.getSubject();
|
||||
_context = SecurityUtils.doAs(subject, newSpnegoContext(subject));
|
||||
_context = SecurityUtils.callAs(subject, newSpnegoContext(subject));
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
|
@ -182,10 +182,11 @@ public class SPNEGOLoginService extends ContainerLifeCycle implements LoginServi
|
|||
gssContext = holder == null ? null : holder.gssContext;
|
||||
}
|
||||
if (gssContext == null)
|
||||
gssContext = SecurityUtils.doAs(subject, newGSSContext());
|
||||
gssContext = SecurityUtils.callAs(subject, newGSSContext());
|
||||
|
||||
|
||||
byte[] input = Base64.getDecoder().decode((String)credentials);
|
||||
byte[] output = SecurityUtils.doAs(_context._subject, acceptGSSContext(gssContext, input));
|
||||
byte[] output = SecurityUtils.callAs(_context._subject, acceptGSSContext(gssContext, input));
|
||||
String token = Base64.getEncoder().encodeToString(output);
|
||||
|
||||
String userName = toUserName(gssContext);
|
||||
|
|
|
@ -22,16 +22,22 @@ import java.util.concurrent.Callable;
|
|||
import java.util.concurrent.CompletionException;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import org.eclipse.jetty.util.JavaVersion;
|
||||
|
||||
/**
|
||||
* <p>Collections of utility methods to deal with the scheduled removal
|
||||
* of the security classes defined by <a href="https://openjdk.org/jeps/411">JEP 411</a>.</p>
|
||||
* <p>To enable usage of a {@link SecurityManager}, the system property {@link #USE_SECURITY_MANAGER} must be set to {@code true}
|
||||
* for JVMs after version 21.</p>
|
||||
*/
|
||||
public class SecurityUtils
|
||||
{
|
||||
private static final MethodHandle doAs = lookupDoAs();
|
||||
public static final boolean USE_SECURITY_MANAGER = Boolean.parseBoolean(
|
||||
System.getProperty("org.eclipse.jetty.util.security.useSecurityManager", JavaVersion.VERSION.getMajor() <= 21 ? "true" : "false"));
|
||||
private static final MethodHandle callAs = lookupCallAs();
|
||||
private static final MethodHandle doPrivileged = lookupDoPrivileged();
|
||||
|
||||
private static MethodHandle lookupDoAs()
|
||||
private static MethodHandle lookupCallAs()
|
||||
{
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
try
|
||||
|
@ -39,14 +45,15 @@ public class SecurityUtils
|
|||
// Subject.doAs() is deprecated for removal and replaced by Subject.callAs().
|
||||
// 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, "callAs", MethodType.methodType(Object.class, Subject.class, Callable.class));
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Lookup the old API.
|
||||
if (!USE_SECURITY_MANAGER)
|
||||
return null;
|
||||
// Otherwise (Java 17), lookup the old API.
|
||||
MethodType oldSignature = MethodType.methodType(Object.class, Subject.class, PrivilegedAction.class);
|
||||
MethodHandle doAs = lookup.findStatic(Subject.class, "doAs", oldSignature);
|
||||
// Convert the Callable used in the new API to the PrivilegedAction used in the old API.
|
||||
|
@ -63,6 +70,8 @@ public class SecurityUtils
|
|||
|
||||
private static MethodHandle lookupDoPrivileged()
|
||||
{
|
||||
if (!USE_SECURITY_MANAGER)
|
||||
return null;
|
||||
try
|
||||
{
|
||||
// Use reflection to work with Java versions that have and don't have AccessController.
|
||||
|
@ -84,6 +93,8 @@ public class SecurityUtils
|
|||
{
|
||||
try
|
||||
{
|
||||
if (!USE_SECURITY_MANAGER)
|
||||
return null;
|
||||
// Use reflection to work with Java versions that have and don't have SecurityManager.
|
||||
return System.class.getMethod("getSecurityManager").invoke(null);
|
||||
}
|
||||
|
@ -102,6 +113,8 @@ public class SecurityUtils
|
|||
*/
|
||||
public static void checkPermission(Permission permission) throws SecurityException
|
||||
{
|
||||
if (!USE_SECURITY_MANAGER)
|
||||
return;
|
||||
Object securityManager = SecurityUtils.getSecurityManager();
|
||||
if (securityManager == null)
|
||||
return;
|
||||
|
@ -129,11 +142,9 @@ public class SecurityUtils
|
|||
*/
|
||||
public static <T> T doPrivileged(PrivilegedAction<T> action)
|
||||
{
|
||||
// Keep this method short and inlineable.
|
||||
MethodHandle methodHandle = doPrivileged;
|
||||
if (methodHandle == null)
|
||||
if (!USE_SECURITY_MANAGER || doPrivileged == null)
|
||||
return action.run();
|
||||
return doPrivileged(methodHandle, action);
|
||||
return doPrivileged(doPrivileged, action);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -153,6 +164,21 @@ public class SecurityUtils
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Runs the given action as the given subject.</p>
|
||||
*
|
||||
* @param subject the subject this action runs as
|
||||
* @param action the action to run
|
||||
* @return the result of the action
|
||||
* @param <T> the type of the result
|
||||
* @deprecated use {@link #callAs(Subject, Callable)}
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "12.1.0")
|
||||
public static <T> T doAs(Subject subject, Callable<T> action)
|
||||
{
|
||||
return callAs(subject, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Runs the given action as the given subject.</p>
|
||||
*
|
||||
|
@ -162,14 +188,14 @@ public class SecurityUtils
|
|||
* @param <T> the type of the result
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T doAs(Subject subject, Callable<T> action)
|
||||
public static <T> T callAs(Subject subject, Callable<T> action)
|
||||
{
|
||||
try
|
||||
{
|
||||
MethodHandle methodHandle = doAs;
|
||||
if (methodHandle == null)
|
||||
if (callAs == null)
|
||||
return action.call();
|
||||
return (T)methodHandle.invoke(subject, action);
|
||||
|
||||
return (T)callAs.invoke(subject, action);
|
||||
}
|
||||
catch (RuntimeException | Error x)
|
||||
{
|
||||
|
|
|
@ -108,7 +108,6 @@ import org.eclipse.jetty.util.component.LifeCycle;
|
|||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.Resources;
|
||||
import org.eclipse.jetty.util.security.SecurityUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -219,7 +218,6 @@ public class ServletContextHandler extends ContextHandler
|
|||
private Logger _logger;
|
||||
private int _maxFormKeys = Integer.getInteger(MAX_FORM_KEYS_KEY, DEFAULT_MAX_FORM_KEYS);
|
||||
private int _maxFormContentSize = Integer.getInteger(MAX_FORM_CONTENT_SIZE_KEY, DEFAULT_MAX_FORM_CONTENT_SIZE);
|
||||
private boolean _usingSecurityManager = getSecurityManager() != null;
|
||||
|
||||
private final List<EventListener> _programmaticListeners = new CopyOnWriteArrayList<>();
|
||||
private final List<ServletContextListener> _servletContextListeners = new CopyOnWriteArrayList<>();
|
||||
|
@ -324,16 +322,17 @@ public class ServletContextHandler extends ContextHandler
|
|||
new DumpableCollection("initparams " + this, getInitParams().entrySet()));
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true, since = "12.1.0")
|
||||
public boolean isUsingSecurityManager()
|
||||
{
|
||||
return _usingSecurityManager;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true, since = "12.1.0")
|
||||
public void setUsingSecurityManager(boolean usingSecurityManager)
|
||||
{
|
||||
if (usingSecurityManager && getSecurityManager() == null)
|
||||
throw new IllegalStateException("No security manager");
|
||||
_usingSecurityManager = usingSecurityManager;
|
||||
if (usingSecurityManager)
|
||||
throw new UnsupportedOperationException("SecurityManager not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1712,11 +1711,6 @@ public class ServletContextHandler extends ContextHandler
|
|||
getContext().destroy(listener);
|
||||
}
|
||||
|
||||
private static Object getSecurityManager()
|
||||
{
|
||||
return SecurityUtils.getSecurityManager();
|
||||
}
|
||||
|
||||
public static class JspPropertyGroup implements JspPropertyGroupDescriptor
|
||||
{
|
||||
private final List<String> _urlPatterns = new ArrayList<>();
|
||||
|
@ -2980,25 +2974,7 @@ public class ServletContextHandler extends ContextHandler
|
|||
@Override
|
||||
public ClassLoader getClassLoader()
|
||||
{
|
||||
// no security manager just return the classloader
|
||||
ClassLoader classLoader = ServletContextHandler.this.getClassLoader();
|
||||
if (isUsingSecurityManager())
|
||||
{
|
||||
// check to see if the classloader of the caller is the same as the context
|
||||
// classloader, or a parent of it, as required by the javadoc specification.
|
||||
ClassLoader callerLoader = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
|
||||
.getCallerClass()
|
||||
.getClassLoader();
|
||||
while (callerLoader != null)
|
||||
{
|
||||
if (callerLoader == classLoader)
|
||||
return classLoader;
|
||||
else
|
||||
callerLoader = callerLoader.getParent();
|
||||
}
|
||||
SecurityUtils.checkPermission(new RuntimePermission("getClassLoader"));
|
||||
}
|
||||
return classLoader;
|
||||
return ServletContextHandler.this.getClassLoader();
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled)
|
||||
|
|
Loading…
Reference in New Issue