Skip to main content

Java authorization internals

Eager versus lazy access checks

The access checking algorithm has been described as computing an intersection of the sets of permissions of all the ProtectionDomains on the call stack. One way of computing this intersection would have been the eager way: A running variable is maintained to keep track of the intersection set for the frames on the stack at any particular instant. As soon as a new frame is put on the stack, the variable is updated by the runtime by intersecting the permissions set for this latest ProtectionDomain with the old value of the variable. The downside of eager access checking is obvious: if in that control flow sequence no call is ever made to the security manager, then the entire effort will have been in vain. Because permission checking usually happens less frequently than cross-ProtectionDomain calls on an average, eager evaluation can be expected to be inefficient.

The second way to compute this intersection is the lazy way previously described: The intersection is computed with respect to the call stack only at the instant the permission check is requested.

As regards its practical implementation, the "computation of the intersection of permission sets" is not implemented as a set operation. Instead, an equivalent approach is followed: Starting from the newest frame on the call stack and moving towards the oldest, the implies() method is called on the ProtectionDomain corresponding to each class on the call stack. If the implies() method returns false at any stage, an AccessControlException is thrown; otherwise the next stack frame in sequence is considered. The correspondence between this approach and the set intersection mechanism described earlier should be clear.

Internally, a call to the implies() method leads to the ProtectionDomain going back to the Policy object and asking for the refreshed security policy (recall that dynamic policy refresh is allowed from the Java 2 platform SDK 1.4 onwards only). The ProtectionDomain then calls the implies() method on the (refreshed) policy object thus returned and passes itself along with the permission to be checked to this method. Inside the implies() method of the Policy object, the up-to-date Permissions set corresponding to the ProtectionDomain specified is obtained from its cache (or re-read from the source, if not yet available in the cache, and subsequently put into the cache) and the called implies() method. As a result, the implies() method is called on the PermissionCollection object contained therein that matches the type of the permission to be checked. As previously discussed, the PermissionCollection will return true if the requested permission matches or is implied by any of the individual permissions contained within it.

Return to article.