public class DynamicPolicyProvider extends AbstractPolicy implements RevocablePolicy, ScalableNestedPolicy
DynamicPolicy
interface, then its
permission mappings are assumed to change only when its refresh
method is called. Permissions are granted on the
granularity of class loader; granting a permission requires (of the calling
context) GrantPermission
for that permission.
This is a Dynamic Policy Provider that supports concurrent access, for instances where a Policy provider is used for a distributed network of computers, or where there is a large number of ProtectionDomains and hence the opportunity for concurrency exists, concurrency comes with a cost however, that of increased memory usage.
Due to the Java 2 Security system's static design, a Policy Provider can only augment policy files; a Policy can only relax security by granting additional permissions, this implementation adds an experimental feature for revoking permissions, however there are some caveats:
A ProtectionDomain must be created with the dynamic constructor otherwise it will never consult the policy. The AccessController.checkPermission(Permission) method consults the current AccessControlContext, which contains all ProtectionDomain's on the current thread's stack, before consulting the AccessControllContext.checkPermission(Permission), it calls AccessControllContext.optimize() which removes all duplicate ProtectionDomains in the ProtectionDomain array[]'s from the enclosing AccessContolContext for the execution domain and the nested AccessControlContext for the privileged domain (the privileged domain is an array of ProtectionDomain's on the stack since the last AccessController.doPriveleged() call). The optimize() method also calls the DomainCombiner, which, for example, gives the SubjectDomainCombiner the opportunity to manipulate the ProtectionDomain's in the privileged array, in the SubjectDomainCombiner's case, it creates new copies of the ProtectionDomain's with new Principal[]'s injected. The optimize() method returns a new optimized AccessControlContext.
Now the AccessController calls the new AccessControlContext.checkPermission(Permission), at this stage, each ProtectionDomain, if created with the dynamic constructor consults the Policy, calling Policy.implies(ProtectionDomain, Permission).
If any calls to the policy return false, the ProtectionDomain then checks its internal Permissions and if they return false, it returns false. The first ProtectionDomain in the AccessControlContext to return false causes the AccessController.checkPermission(Permission) to throw an AccessControlException
To optimise the time taken to check Permission's the ProtectionDomain's should either be static, which excludes the Policy, or dynamic with a null PermissionCollection in it's constructor,
So in order to prevent dynamic grants from finding their way into a ProtectionDomain's private PermissionCollection, this policy ensures that no dynamically grantable permissions are returned via the method:
getPermissions(Codesource source) as a precaution.
This is different to the behaviour of the previous Jini 2.0 DynamicPolicyProvider implementation where dynamically granted Permissions could escape into the ProtectionDomain's private PermissionCollection. /p>
It is thus recommended that Static policy files only be used for setting up your privileged code and use UmbrellaGrantPermission's and grant all other Permission's using dynamic grants.
The underlying policy provider may be set using the System property:
,net.jini.security.policy.PolicyFileProvider.basePolicyClass = org.apache.river.security.concurrent.ConcurrentPolicyFile
ProtectionDomain
,
Policy
,
ConcurrentPolicyFile
,
PolicyFileProvider
,
CachingSecurityManager
,
RemotePolicy
Policy.Parameters
ALL_PERMISSION, comparator, umbrella
UNSUPPORTED_EMPTY_COLLECTION
Constructor and Description |
---|
DynamicPolicyProvider()
Creates a new
DynamicPolicyProvider instance that wraps a
default underlying policy. |
DynamicPolicyProvider(Policy basePolicy)
Creates a new
DynamicPolicyProvider instance that wraps
around the given non-null base policy object. |
Modifier and Type | Method and Description |
---|---|
Permission[] |
getGrants(Class cl,
Principal[] principals)
If this security policy provider supports dynamic permission grants,
returns a new array containing the cumulative set of permissions
dynamically granted to protection domains (including ones not yet
created) that are associated with the class loader of the given class
and possess at least the given set of principals.
|
List<PermissionGrant> |
getPermissionGrants(ProtectionDomain domain)
Returns a new List containing immutable PermissionGrant's, the
List returned is not synchronised and must not be shared with policy
internal state.
|
PermissionCollection |
getPermissions(CodeSource codesource) |
PermissionCollection |
getPermissions(ProtectionDomain domain) |
void |
grant(Class cl,
Principal[] principals,
Permission[] permissions)
If this security policy provider supports dynamic permission grants,
grants the specified permissions to all protection domains (including
ones not yet created) that are associated with the class loader of the
given class and possess at least the given set of principals.
|
boolean |
grant(PermissionGrant p)
A dynamic grant.
|
boolean |
grantSupported()
Returns
true if this policy provider supports dynamic
permission grants; returns false otherwise. |
boolean |
implies(ProtectionDomain domain,
Permission permission) |
void |
refresh()
Calling refresh doesn't remove any dynamic grant's, it only clears
the cache and refreshes the underlying Policy, it also removes any
grants for ProtectionDomains that no longer exist.
|
boolean |
revokeSupported()
Checks if policy supports revocation.
|
checkCallerHasGrants, checkNullElements, convert, expandUmbrella, extractGrantFromPolicy, processGrants
getInstance, getInstance, getInstance, getParameters, getPolicy, getProvider, getType, setPolicy
public DynamicPolicyProvider() throws PolicyInitializationException
DynamicPolicyProvider
instance that wraps a
default underlying policy. The underlying policy is created as follows:
if the
net.jini.security.policy.DynamicPolicyProvider.basePolicyClass
security property is set, then its value is interpreted as the class
name of the base (underlying) policy provider; otherwise, a default
class name of
"net.jini.security.policy.PolicyFileProvider"
is used. The base policy is then instantiated using the no-arg public
constructor of the named class. If the base policy class is not found,
is not instantiable via a public no-arg constructor, or if invocation of
its constructor fails, then a PolicyInitializationException
is thrown.
Note that this constructor requires the appropriate
"getProperty"
SecurityPermission
to
read the
net.jini.security.policy.DynamicPolicyProvider.basePolicyClass
security property, and may require "accessClassInPackage.*"
RuntimePermission
s, depending on the package of the base policy
class.
PolicyInitializationException
- if unable to construct the base
policySecurityException
- if there is a security manager and the
calling context does not have adequate permissions to read the
net.jini.security.policy.DynamicPolicyProvider.basePolicyClass
security property, or if the calling context does not have
adequate permissions to access the base policy classpublic DynamicPolicyProvider(Policy basePolicy)
DynamicPolicyProvider
instance that wraps
around the given non-null
base policy object.basePolicy
- base policy object containing information about
non-dynamic grantsNullPointerException
- if basePolicy
is
null
public boolean revokeSupported()
RevocablePolicy
revokeSupported
in interface RevocablePolicy
public PermissionCollection getPermissions(CodeSource codesource)
getPermissions
in class Policy
public PermissionCollection getPermissions(ProtectionDomain domain)
getPermissions
in class Policy
public boolean implies(ProtectionDomain domain, Permission permission)
public void refresh()
public boolean grantSupported()
DynamicPolicy
true
if this policy provider supports dynamic
permission grants; returns false
otherwise. Note that this
method may return different values for a given
DynamicPolicy
instance, depending on context. For example,
a policy provider that delegates to different underlying policy
implementations depending on thread state would return true
from this method when the current delegate supports dynamic permission
grants, but return false
when another delegate lacking such
support is in effect.grantSupported
in interface DynamicPolicy
true
if policy supports dynamic permission grants
under current context, false
otherwisepublic void grant(Class cl, Principal[] principals, Permission[] permissions)
DynamicPolicy
null
, then the grant applies across all
protection domains that possess at least the specified principals. If
the list of principals is null
or empty, then principals
are effectively ignored in determining the protection domains to which
the grant applies. If this policy provider does not support dynamic
permission grants, then no permissions are granted and an
UnsupportedOperationException
is thrown.
The given class, if non-null
, must belong to either the
system domain or a protection domain whose associated class loader is
non-null
. If the class does not belong to such a
protection domain, then no permissions are granted and an
UnsupportedOperationException
is thrown.
If a security manager is installed, its checkPermission
method is called with a GrantPermission
containing the
permissions to grant; if the permission check fails, then no permissions
are granted and the resulting SecurityException
is thrown.
The principals and permissions arrays passed in are neither modified nor
retained; subsequent changes to the arrays have no effect on the grant
operation.
grant
in interface DynamicPolicy
cl
- class to grant permissions to the class loader of, or
null
if granting across all class loadersprincipals
- if non-null
, minimum set of principals
to which grants applypermissions
- if non-null
, permissions to grantpublic Permission[] getGrants(Class cl, Principal[] principals)
DynamicPolicy
null
, then this method returns the cumulative set of
permissions dynamically granted across all protection domains that
possess at least the specified principals (i.e., through calls to the
grant method where the specified class was null
). If the
list of principals is null
or empty, then the permissions
returned reflect only grants not qualified by principals (i.e., those
performed through calls to the grant method where the specified
principals array was null
or empty). If this policy
provider does not support dynamic permission grants, then an
UnsupportedOperationException
is thrown.
The given class, if non-null
, must belong to either the
system domain or a protection domain whose associated class loader is
non-null
. If the class does not belong to such a
protection domain, then an UnsupportedOperationException
is
thrown.
getGrants
in interface DynamicPolicy
cl
- class to query the permissions dynamically granted to the
class loader of, or null
if querying permissions
granted across all class loadersprincipals
- if non-null
, principals to query
dynamic grants forpublic List<PermissionGrant> getPermissionGrants(ProtectionDomain domain)
ScalableNestedPolicy
getPermissionGrants
in interface ScalableNestedPolicy
public boolean grant(PermissionGrant p)
RevocablePolicy
grant
in interface RevocablePolicy
Copyright 2007-2013, multiple authors.
Licensed under the Apache License, Version 2.0, see the NOTICE file for attributions.