I have been pondering whether to add the following method to
RevocablePolicy:
public Collection<PermissionGrant> getPermissionGrants(boolean recursive);
This method could enable a developer to query individual
PermissionGrants before revoking, however since PermissionGrant
implementations are private, a developer can never be 100% sure of the
effect of removing it. For instance a PermissionGrant may apply
generally, not just to the ProtectionDomain concerning the developer.
In fact, it is the PermissionGrant itself, or the entity that created
it, that is best suited to determining if and when it should be revoked.
For example, if a Subject is granted a Permission to access a resource
only for 24 hours, then after this period a PermissionGrant can return
isVoid() if queried.
However, since our new SecurityManager caches the results of permission
checks, the permission will continue to remain granted until the Policy
is refereshed. Upon refresh, all void PermissionGrant's are
automatically removed by the Policy.
A user developer can use decorators, to add functionality to
PermissionGrant, and intercept the isVoid() method based on conditions.
So in reality, even the revoke method is not required:
public boolean revoke(PermissionGrant p);
Instead it makes much more sense to use Event notifications and
decorators to effect revocation, in this case a PermissionGrant
decorator can be notified of an event and Policy.refresh() called, the
Policy itself removes the PermissionGrant.
PermissionGrants may be used to grant permissions temporarily, for
example place a cap on network traffic for Subjects, refreshed monthly,
daily or weekly.
A DelegateSocket (Delegates will be distributed separately) might notify
some kind of grant manager that in turn notifies the PermissionGrant
that conditions have changed and also refresh the policy. The
PermissionGrant may still be valid and doesn't need to be removed from
the policy, the grant manager may notify the PermissionGrant when
conditions have returned to normal, again the policy must be refreshed
when conditions change.
The Policy.refresh() call is non blocking with our new policy providers
and SecurityManager cache, allowing security policy checks to continue
concurrently while a refresh is in progress.
Depending on conditions, it the developer may by satisfied to simply
refresh the policy periodically independent of conditions, but this
decision is left to implementers.
Regards,
Peter.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.river.api.security;
import java.security.Permission;
import java.security.Principal;
import net.jini.security.policy.DynamicPolicy;
/**
* <p>
* RevocablePolicy, is a Java Security Policy Provider that supports
* Runtime Dynamic addition and removal of PermissionGrant's
* </p><p>
* Warning: Not all Permission's are truly revocable, while any
Permission can
* be dynamically added and later removed from this policy, many JVM
Permission
* implementations are used in ways that allow references to escape
* </p><p>
* To quote Tim Blackman, from river-dev:
* </p><p><CITE>
* I remember talking with Bob and Mike Warres about this. The problem with
* removing permission grants is that when code is granted a permission,
* it can very likely squirrel away something -- an object, or another
* capability available through the granted permission -- that will permit
* it to perform the same operation again without the JVM checking for
* the permission again.
* </CITE>
* </p><p>
* In order for a Permission to be fully revoked, the permission must be
* used to guard methods only, not Objects or their creation. A Security
* Delegate, may be used as a wrapper with an identical interface to the
object
* it protects, a new Permission class must be implemented, for the
Delegate's
* use, in a checkPermission call, to protect access to the underlying
* object's method. If an existing JVM Permission guards the underlying
object,
* the delegate needs to be given the standard JVM Permission.
DelegatePermission
* has been created for the purpose of encapsulating an existing Permission.
* </p><p>
* The ability to revoke a Permission fully is intended for smart proxy's to
* be given some trust temporarily, so that objects received from the
smart proxy
* by a client cannot be used to continue gathering and sending
information to
* a remote server after the proxy has been discarded.
* </p><p>
* A list of standard Java Permission's that are confirmed safely
* revocable will be provided here.
* </p>
* @author Peter Firmstone
* @see java.security.Policy
* @see java.security.ProtectionDomain
* @see java.security.AccessController
* @see java.security.DomainCombiner
* @see java.security.AccessControlContext
* @see java.security.Permission
* @see PermissionGrant
* @see DelegatePermission
*/
public interface RevocablePolicy extends DynamicPolicy {
/**
* Revokes a specific PermissionGrant from the Policy.
*
* Caveat: Not all Permission's once granted can be revoked. When a
Permission
* is checked, prior to passing a reference to a caller, that reference
* has escaped any further Permission checks, meaning that the
Permission
* cannot be revoked for the caller holding a reference.
*
* Note that after revocation, the caller should call
Policy.getPermissions
* to determine if the proxy has no or minimal permissions. If the
* proxy still retains permission, the caller should throw a
SecurityException.
*
* @param p
* @return true if successful
*/
public boolean revoke(PermissionGrant p);
/**
* A dynamic grant.
* @param p
* @return true if successful
*/
public boolean grant(PermissionGrant p);
/**
*
* @return true - If Revoke supported by underlying policy.
*/
public boolean revokeSupported();
}