AccessControllerpublic final class AccessController extends Object {@code AccessController} provides static methods to perform access control
checks and privileged operations. |
Fields Summary |
---|
private static final WeakHashMap | contextsA map used to store a mapping between a given Thread and
AccessControllerContext-s used in successive calls of doPrivileged(). A
WeakHashMap is used to allow automagical wiping of the dead threads from
the map. The thread (normally Thread.currentThread()) is used as a key
for the map, and a value is ArrayList where all AccessControlContext-s
are stored.
((ArrayList)contexts.get(Thread.currentThread())).lastElement() - is
reference to the latest context passed to the doPrivileged() call. |
Constructors Summary |
---|
private AccessController()
throw new Error("statics only.");
|
Methods Summary |
---|
public static void | checkPermission(java.security.Permission perm)Checks the specified permission against the vm's current security policy.
The check is performed in the context of the current thread. This method
returns silently if the permission is granted, otherwise an {@code
AccessControlException} is thrown.
A permission is considered granted if every {@link ProtectionDomain} in
the current execution context has been granted the specified permission.
If privileged operations are on the execution context, only the {@code
ProtectionDomain}s from the last privileged operation are taken into
account.
This method delegates the permission check to
{@link AccessControlContext#checkPermission(Permission)} on the current
callers' context obtained by {@link #getContext()}.
if (perm == null) {
throw new NullPointerException("permission can not be null");
}
getContext().checkPermission(perm);
| public static T | doPrivileged(java.security.PrivilegedAction action)Returns the result of executing the specified privileged action. Only the
{@code ProtectionDomain} of the direct caller of this method and the
{@code ProtectionDomain}s of all subsequent classes in the call chain are
checked to be granted the necessary permission if access checks are
performed.
If an instance of {@code RuntimeException} is thrown during the execution
of the {@code PrivilegedAction#run()} method of the given action, it will
be propagated through this method.
if (action == null) {
throw new NullPointerException("action can not be null");
}
return doPrivilegedImpl(action, null);
| public static T | doPrivileged(java.security.PrivilegedAction action, java.security.AccessControlContext context)Returns the result of executing the specified privileged action. The
{@code ProtectionDomain} of the direct caller of this method, the {@code
ProtectionDomain}s of all subsequent classes in the call chain and all
{@code ProtectionDomain}s of the given context are checked to be granted
the necessary permission if access checks are performed.
If an instance of {@code RuntimeException} is thrown during the execution
of the {@code PrivilegedAction#run()} method of the given action, it will
be propagated through this method.
if (action == null) {
throw new NullPointerException("action can not be null");
}
return doPrivilegedImpl(action, context);
| public static T | doPrivileged(java.security.PrivilegedExceptionAction action)Returns the result of executing the specified privileged action. Only the
{@code ProtectionDomain} of the direct caller of this method and the
{@code ProtectionDomain}s of all subsequent classes in the call chain are
checked to be granted the necessary permission if access checks are
performed.
If a checked exception is thrown by the action's run method, it will be
wrapped and propagated through this method.
If an instance of {@code RuntimeException} is thrown during the execution
of the {@code PrivilegedAction#run()} method of the given action, it will
be propagated through this method.
if (action == null) {
throw new NullPointerException("action can not be null");
}
return doPrivilegedImpl(action, null);
| public static T | doPrivileged(java.security.PrivilegedExceptionAction action, java.security.AccessControlContext context)Returns the result of executing the specified privileged action. The
{@code ProtectionDomain} of the direct caller of this method, the {@code
ProtectionDomain}s of all subsequent classes in the call chain and all
{@code ProtectionDomain}s of the given context are checked to be granted
the necessary permission if access checks are performed.
If a checked exception is thrown by the action's run method, it will be
wrapped and propagated through this method.
If an instance of {@code RuntimeException} is thrown during the execution
of the {@code PrivilegedAction#run()} method of the given action, it will
be propagated through this method.
if (action == null) {
throw new NullPointerException("action can not be null");
}
return doPrivilegedImpl(action, context);
| private static T | doPrivilegedImpl(java.security.PrivilegedExceptionAction action, java.security.AccessControlContext context)The real implementation of doPrivileged() method. It pushes the passed
context into this thread's contexts stack, and then invokes
action.run() . The pushed context is then investigated in the
{@link #getContext()} which is called in the {@link #checkPermission}.
Thread currThread = Thread.currentThread();
ArrayList<AccessControlContext> a = null;
try {
// currThread==null means that VM warm up is in progress
if (currThread != null && contexts != null) {
synchronized (contexts) {
a = contexts.get(currThread);
if (a == null) {
a = new ArrayList<AccessControlContext>();
contexts.put(currThread, a);
}
}
a.add(context);
}
return action.run();
} catch (Exception ex) {
// Errors automagically go through - they are not catched by this
// block
// Unchecked exceptions must pass through without modification
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
// All other (==checked) exceptions get wrapped
throw new PrivilegedActionException(ex);
} finally {
if (currThread != null) {
// No need to sync() here, as each given 'a' will be accessed
// only from one Thread. 'contexts' still need sync() however,
// as it's accessed from different threads simultaneously
if (a != null) {
// it seems I will never have here [v.size() == 0]
a.remove(a.size() - 1);
}
}
}
| private static T | doPrivilegedImpl(java.security.PrivilegedAction action, java.security.AccessControlContext context)The real implementation of appropriate doPrivileged() method.
It pushes the passed context into this thread's stack of contexts and
then invokes action.run() .
The pushed context is then investigated in the {@link #getContext()}
which is called in the {@link #checkPermission}.
Thread currThread = Thread.currentThread();
if (currThread == null || contexts == null) {
// Big boom time - VM is starting... No need to check permissions:
// 1st, I do believe there is no malicious code available here for
// this moment
// 2d, I cant use currentThread() as a key anyway - when it will
// turn into the real Thread, I'll be unable to retrieve the value
// stored with 'currThread==null' as a key.
return action.run();
}
ArrayList<AccessControlContext> a = null;
try {
synchronized (contexts) {
a = contexts.get(currThread);
if (a == null) {
a = new ArrayList<AccessControlContext>();
contexts.put(currThread, a);
}
}
a.add(context);
return action.run();
} finally {
// No need to sync() here, as each given 'a' will be accessed
// only from one Thread. 'contexts' still need sync() however,
// as it's accessed from different threads simultaneously
if (a != null) {
a.remove(a.size() - 1);
}
}
| public static java.security.AccessControlContext | getContext()Returns the {@code AccessControlContext} for the current {@code Thread}
including the inherited access control context of the thread that spawned
the current thread (recursively).
The returned context may be used to perform access checks at a later
point in time, possibly by another thread.
// duplicates (if any) will be removed in ACC constructor
ProtectionDomain[] stack = getStackDomains();
Thread currThread = Thread.currentThread();
if (currThread == null || contexts == null) {
// Big boo time. No need to check anything ?
return new AccessControlContext(stack);
}
ArrayList<AccessControlContext> threadContexts;
synchronized (contexts) {
threadContexts = contexts.get(currThread);
}
AccessControlContext that;
if ((threadContexts == null) || (threadContexts.size() == 0)) {
// We were not in doPrivileged method, so
// have inherited context here
that = SecurityUtils.getContext(currThread);
} else {
// We were in doPrivileged method, so
// Use context passed to the doPrivileged()
that = threadContexts.get(threadContexts.size() - 1);
}
if (that != null && that.combiner != null) {
ProtectionDomain[] assigned = null;
if (that.context != null && that.context.length != 0) {
assigned = new ProtectionDomain[that.context.length];
System.arraycopy(that.context, 0, assigned, 0, assigned.length);
}
ProtectionDomain[] allpds = that.combiner.combine(stack, assigned);
if (allpds == null) {
allpds = new ProtectionDomain[0];
}
return new AccessControlContext(allpds, that.combiner);
}
return new AccessControlContext(stack, that);
| private static native java.security.ProtectionDomain[] | getStackDomains()Returns array of ProtectionDomains from the classes residing on the stack
of the current thread, up to and including the caller of the nearest
privileged frame. Reflection frames are skipped. The returned array is
never null and never contains null elements, meaning that bootstrap
classes are effectively ignored.
|
|