All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.util.security.SecurityUtils Maven / Gradle / Ivy

The newest version!
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.util.security;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionException;
import javax.security.auth.Subject;

/**
 * 

Collections of utility methods to deal with the scheduled removal * of the security classes defined by JEP 411.

*/ public class SecurityUtils { private static final MethodHandle callAs = lookupCallAs(); private static final MethodHandle doPrivileged = lookupDoPrivileged(); private static final MethodHandle getSecurityManager = lookupGetSecurityManager(); private static final MethodHandle checkPermission = lookupCheckPermission(); private static MethodHandle lookupCallAs() { MethodHandles.Lookup lookup = MethodHandles.lookup(); try { // 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). return lookup.findStatic(Subject.class, "callAs", MethodType.methodType(Object.class, Subject.class, Callable.class)); } catch (Throwable x) { try { // 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. MethodType convertSignature = MethodType.methodType(PrivilegedAction.class, Callable.class); MethodHandle converter = lookup.findStatic(SecurityUtils.class, "callableToPrivilegedAction", convertSignature); return MethodHandles.filterArguments(doAs, 1, converter); } catch (Throwable t) { return null; } } } private static MethodHandle lookupDoPrivileged() { try { // Use reflection to work with Java versions that have and don't have AccessController. Class klass = ClassLoader.getPlatformClassLoader().loadClass("java.security.AccessController"); MethodHandles.Lookup lookup = MethodHandles.lookup(); return lookup.findStatic(klass, "doPrivileged", MethodType.methodType(Object.class, PrivilegedAction.class)); } catch (Throwable x) { return null; } } private static MethodHandle lookupGetSecurityManager() { try { // Use reflection to work with Java versions that have and don't have System.getSecurityManager(). MethodHandles.Lookup lookup = MethodHandles.lookup(); return lookup.findStatic(java.lang.System.class, "getSecurityManager", MethodType.methodType(Object.class)); } catch (Throwable x) { return null; } } private static MethodHandle lookupCheckPermission() { try { // Use reflection to work with Java versions that have and don't have SecurityManager. Class klass = ClassLoader.getPlatformClassLoader().loadClass("java.lang.SecurityManager"); MethodHandles.Lookup lookup = MethodHandles.lookup(); return lookup.findVirtual(klass, "checkPermission", MethodType.methodType(Void.class, Permission.class)); } catch (Throwable x) { return null; } } /** * Get the current security manager, if available. * @return the current security manager, if available */ public static Object getSecurityManager() { if (getSecurityManager == null) { return null; } try { return getSecurityManager.invoke(); } catch (Throwable ignored) { return null; } } /** *

Checks the given permission, if the {@link #getSecurityManager() security manager} * is set.

* * @param permission the permission to check * @throws SecurityException if the permission check fails */ public static void checkPermission(Permission permission) throws SecurityException { if (getSecurityManager == null || checkPermission == null) { return; } Object securityManager = SecurityUtils.getSecurityManager(); if (securityManager == null) return; try { checkPermission.invoke(securityManager, permission); } catch (SecurityException | NullPointerException x) { throw x; } catch (Throwable ignored) { } } /** *

Runs the given action with the calling context restricted * to just the calling frame, not all the frames in the stack.

* * @param action the action to run * @return the result of running the action * @param the type of the result */ public static T doPrivileged(PrivilegedAction action) { if (doPrivileged == null) return action.run(); return doPrivileged(doPrivileged, action); } @SuppressWarnings("unchecked") private static T doPrivileged(MethodHandle doPrivileged, PrivilegedAction action) { try { return (T)doPrivileged.invoke(action); } catch (RuntimeException | Error x) { throw x; } catch (Throwable x) { throw new RuntimeException(x); } } /** *

Runs the action as the given subject.

* * @param subject the subject this action runs as * @param action the action to run * @return the result of the action * @param the type of the result * @deprecated use {@link #callAs(Subject, Callable)} */ @Deprecated(forRemoval = true, since = "12.1.0") public static T doAs(Subject subject, Callable action) { return callAs(subject, action); } /** *

Runs the given action as the given subject.

* * @param subject the subject this action runs as * @param action the action to run * @return the result of the action * @param the type of the result */ @SuppressWarnings("unchecked") public static T callAs(Subject subject, Callable action) { try { if (callAs == null) return action.call(); return (T)callAs.invoke(subject, action); } catch (RuntimeException | Error x) { throw x; } catch (Throwable x) { throw new CompletionException(x); } } private static PrivilegedAction callableToPrivilegedAction(Callable callable) { return () -> { try { return callable.call(); } catch (RuntimeException x) { throw x; } catch (Exception x) { throw new RuntimeException(x); } }; } private SecurityUtils() { } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy