There is only one Policy object installed in the runtime at any * given time. A Policy object can be installed by calling the * {@code setPolicy} method. The installed Policy object can be * obtained by calling the {@code getPolicy} method. * *
If no Policy object has been installed in the runtime, a call to * {@code getPolicy} installs an instance of the default Policy * implementation (a default subclass implementation of this abstract class). * The default Policy implementation can be changed by setting the value * of the {@code policy.provider} security property to the fully qualified * name of the desired Policy subclass implementation. * *
Application code can directly subclass Policy to provide a custom * implementation. In addition, an instance of a Policy object can be * constructed by invoking one of the {@code getInstance} factory methods * with a standard type. The default policy type is "JavaPolicy". * *
Once a Policy instance has been installed (either by default, or by * calling {@code setPolicy}), the Java runtime invokes its * {@code implies} method when it needs to * determine whether executing code (encapsulated in a ProtectionDomain) * can perform SecurityManager-protected operations. How a Policy object * retrieves its policy data is up to the Policy implementation itself. * The policy data may be stored, for example, in a flat ASCII file, * in a serialized binary file of the Policy class, or in a database. * *
The {@code refresh} method causes the policy object to
* refresh/reload its data. This operation is implementation-dependent.
* For example, if the policy object stores its data in configuration files,
* calling {@code refresh} will cause it to re-read the configuration
* policy files. If a refresh operation is not supported, this method does
* nothing. Note that refreshed policy may not have an effect on classes
* in a particular ProtectionDomain. This is dependent on the Policy
* provider's implementation of the {@code implies}
* method and its PermissionCollection caching strategy.
*
* @author Roland Schemers
* @author Gary Ellison
* @see java.security.Provider
* @see java.security.ProtectionDomain
* @see java.security.Permission
* @see java.security.Security security properties
*/
public abstract class Policy {
/**
* A read-only empty PermissionCollection instance.
* @since 1.6
*/
public static final PermissionCollection UNSUPPORTED_EMPTY_COLLECTION =
new UnsupportedEmptyCollection();
// Information about the system-wide policy.
private static class PolicyInfo {
// the system-wide policy
final Policy policy;
// a flag indicating if the system-wide policy has been initialized
final boolean initialized;
PolicyInfo(Policy policy, boolean initialized) {
this.policy = policy;
this.initialized = initialized;
}
}
// PolicyInfo is stored in an AtomicReference
private static AtomicReference
This method traverses the list of registered security providers, * starting with the most preferred Provider. * A new Policy object encapsulating the * PolicySpi implementation from the first * Provider that supports the specified type is returned. * *
Note that the list of registered providers may be retrieved via * the {@link Security#getProviders() Security.getProviders()} method. * * @param type the specified Policy type. See the Policy section in the * * Java Cryptography Architecture Standard Algorithm Name Documentation * for a list of standard Policy types. * * @param params parameters for the Policy, which may be null. * * @return the new Policy object. * * @exception SecurityException if the caller does not have permission * to get a Policy instance for the specified type. * * @exception NullPointerException if the specified type is null. * * @exception IllegalArgumentException if the specified parameters * are not understood by the PolicySpi implementation * from the selected Provider. * * @exception NoSuchAlgorithmException if no Provider supports a PolicySpi * implementation for the specified type. * * @see Provider * @since 1.6 */ public static Policy getInstance(String type, Policy.Parameters params) throws NoSuchAlgorithmException { checkPermission(type); try { GetInstance.Instance instance = GetInstance.getInstance("Policy", PolicySpi.class, type, params); return new PolicyDelegate((PolicySpi)instance.impl, instance.provider, type, params); } catch (NoSuchAlgorithmException nsae) { return handleException(nsae); } } /** * Returns a Policy object of the specified type. * *
A new Policy object encapsulating the * PolicySpi implementation from the specified provider * is returned. The specified provider must be registered * in the provider list. * *
Note that the list of registered providers may be retrieved via * the {@link Security#getProviders() Security.getProviders()} method. * * @param type the specified Policy type. See the Policy section in the * * Java Cryptography Architecture Standard Algorithm Name Documentation * for a list of standard Policy types. * * @param params parameters for the Policy, which may be null. * * @param provider the provider. * * @return the new Policy object. * * @exception SecurityException if the caller does not have permission * to get a Policy instance for the specified type. * * @exception NullPointerException if the specified type is null. * * @exception IllegalArgumentException if the specified provider * is null or empty, * or if the specified parameters are not understood by * the PolicySpi implementation from the specified provider. * * @exception NoSuchProviderException if the specified provider is not * registered in the security provider list. * * @exception NoSuchAlgorithmException if the specified provider does not * support a PolicySpi implementation for the specified type. * * @see Provider * @since 1.6 */ public static Policy getInstance(String type, Policy.Parameters params, String provider) throws NoSuchProviderException, NoSuchAlgorithmException { if (provider == null || provider.length() == 0) { throw new IllegalArgumentException("missing provider"); } checkPermission(type); try { GetInstance.Instance instance = GetInstance.getInstance("Policy", PolicySpi.class, type, params, provider); return new PolicyDelegate((PolicySpi)instance.impl, instance.provider, type, params); } catch (NoSuchAlgorithmException nsae) { return handleException(nsae); } } /** * Returns a Policy object of the specified type. * *
A new Policy object encapsulating the * PolicySpi implementation from the specified Provider * object is returned. Note that the specified Provider object * does not have to be registered in the provider list. * * @param type the specified Policy type. See the Policy section in the * * Java Cryptography Architecture Standard Algorithm Name Documentation * for a list of standard Policy types. * * @param params parameters for the Policy, which may be null. * * @param provider the Provider. * * @return the new Policy object. * * @exception SecurityException if the caller does not have permission * to get a Policy instance for the specified type. * * @exception NullPointerException if the specified type is null. * * @exception IllegalArgumentException if the specified Provider is null, * or if the specified parameters are not understood by * the PolicySpi implementation from the specified Provider. * * @exception NoSuchAlgorithmException if the specified Provider does not * support a PolicySpi implementation for the specified type. * * @see Provider * @since 1.6 */ public static Policy getInstance(String type, Policy.Parameters params, Provider provider) throws NoSuchAlgorithmException { if (provider == null) { throw new IllegalArgumentException("missing provider"); } checkPermission(type); try { GetInstance.Instance instance = GetInstance.getInstance("Policy", PolicySpi.class, type, params, provider); return new PolicyDelegate((PolicySpi)instance.impl, instance.provider, type, params); } catch (NoSuchAlgorithmException nsae) { return handleException(nsae); } } private static Policy handleException(NoSuchAlgorithmException nsae) throws NoSuchAlgorithmException { Throwable cause = nsae.getCause(); if (cause instanceof IllegalArgumentException) { throw (IllegalArgumentException)cause; } throw nsae; } /** * Return the Provider of this Policy. * *
This Policy instance will only have a Provider if it * was obtained via a call to {@code Policy.getInstance}. * Otherwise this method returns null. * * @return the Provider of this Policy, or null. * * @since 1.6 */ public Provider getProvider() { return null; } /** * Return the type of this Policy. * *
This Policy instance will only have a type if it * was obtained via a call to {@code Policy.getInstance}. * Otherwise this method returns null. * * @return the type of this Policy, or null. * * @since 1.6 */ public String getType() { return null; } /** * Return Policy parameters. * *
This Policy instance will only have parameters if it * was obtained via a call to {@code Policy.getInstance}. * Otherwise this method returns null. * * @return Policy parameters, or null. * * @since 1.6 */ public Policy.Parameters getParameters() { return null; } /** * Return a PermissionCollection object containing the set of * permissions granted to the specified CodeSource. * *
Applications are discouraged from calling this method * since this operation may not be supported by all policy implementations. * Applications should solely rely on the {@code implies} method * to perform policy checks. If an application absolutely must call * a getPermissions method, it should call * {@code getPermissions(ProtectionDomain)}. * *
The default implementation of this method returns * Policy.UNSUPPORTED_EMPTY_COLLECTION. This method can be * overridden if the policy implementation can return a set of * permissions granted to a CodeSource. * * @param codesource the CodeSource to which the returned * PermissionCollection has been granted. * * @return a set of permissions granted to the specified CodeSource. * If this operation is supported, the returned * set of permissions must be a new mutable instance * and it must support heterogeneous Permission types. * If this operation is not supported, * Policy.UNSUPPORTED_EMPTY_COLLECTION is returned. */ public PermissionCollection getPermissions(CodeSource codesource) { return Policy.UNSUPPORTED_EMPTY_COLLECTION; } /** * Return a PermissionCollection object containing the set of * permissions granted to the specified ProtectionDomain. * *
Applications are discouraged from calling this method * since this operation may not be supported by all policy implementations. * Applications should rely on the {@code implies} method * to perform policy checks. * *
The default implementation of this method first retrieves * the permissions returned via {@code getPermissions(CodeSource)} * (the CodeSource is taken from the specified ProtectionDomain), * as well as the permissions located inside the specified ProtectionDomain. * All of these permissions are then combined and returned in a new * PermissionCollection object. If {@code getPermissions(CodeSource)} * returns Policy.UNSUPPORTED_EMPTY_COLLECTION, then this method * returns the permissions contained inside the specified ProtectionDomain * in a new PermissionCollection object. * *
This method can be overridden if the policy implementation
* supports returning a set of permissions granted to a ProtectionDomain.
*
* @param domain the ProtectionDomain to which the returned
* PermissionCollection has been granted.
*
* @return a set of permissions granted to the specified ProtectionDomain.
* If this operation is supported, the returned
* set of permissions must be a new mutable instance
* and it must support heterogeneous Permission types.
* If this operation is not supported,
* Policy.UNSUPPORTED_EMPTY_COLLECTION is returned.
*
* @since 1.4
*/
public PermissionCollection getPermissions(ProtectionDomain domain) {
PermissionCollection pc = null;
if (domain == null)
return new Permissions();
if (pdMapping == null) {
initPolicy(this);
}
synchronized (pdMapping) {
pc = pdMapping.get(domain.key);
}
if (pc != null) {
Permissions perms = new Permissions();
synchronized (pc) {
for (Enumeration
The default implementation of this method does nothing.
* This method should be overridden if a refresh operation is supported
* by the policy implementation.
*/
public void refresh() { }
/**
* This subclass is returned by the getInstance calls. All Policy calls
* are delegated to the underlying PolicySpi.
*/
private static class PolicyDelegate extends Policy {
private PolicySpi spi;
private Provider p;
private String type;
private Policy.Parameters params;
private PolicyDelegate(PolicySpi spi, Provider p,
String type, Policy.Parameters params) {
this.spi = spi;
this.p = p;
this.type = type;
this.params = params;
}
@Override public String getType() { return type; }
@Override public Policy.Parameters getParameters() { return params; }
@Override public Provider getProvider() { return p; }
@Override
public PermissionCollection getPermissions(CodeSource codesource) {
return spi.engineGetPermissions(codesource);
}
@Override
public PermissionCollection getPermissions(ProtectionDomain domain) {
return spi.engineGetPermissions(domain);
}
@Override
public boolean implies(ProtectionDomain domain, Permission perm) {
return spi.engineImplies(domain, perm);
}
@Override
public void refresh() {
spi.engineRefresh();
}
}
/**
* This represents a marker interface for Policy parameters.
*
* @since 1.6
*/
public static interface Parameters { }
/**
* This class represents a read-only empty PermissionCollection object that
* is returned from the {@code getPermissions(CodeSource)} and
* {@code getPermissions(ProtectionDomain)}
* methods in the Policy class when those operations are not
* supported by the Policy implementation.
*/
private static class UnsupportedEmptyCollection
extends PermissionCollection {
private static final long serialVersionUID = -8492269157353014774L;
private Permissions perms;
/**
* Create a read-only empty PermissionCollection object.
*/
public UnsupportedEmptyCollection() {
this.perms = new Permissions();
perms.setReadOnly();
}
/**
* Adds a permission object to the current collection of permission
* objects.
*
* @param permission the Permission object to add.
*
* @exception SecurityException - if this PermissionCollection object
* has been marked readonly
*/
@Override public void add(Permission permission) {
perms.add(permission);
}
/**
* Checks to see if the specified permission is implied by the
* collection of Permission objects held in this PermissionCollection.
*
* @param permission the Permission object to compare.
*
* @return true if "permission" is implied by the permissions in
* the collection, false if not.
*/
@Override public boolean implies(Permission permission) {
return perms.implies(permission);
}
/**
* Returns an enumeration of all the Permission objects in the
* collection.
*
* @return an enumeration of all the Permissions.
*/
@Override public Enumeration