Protection Domains The Access Controller

stack trace is a little more complicated than the one weve just shown −− in this case, were relying on the fact that the constructor of the Socket class indirectly calls the access controller because, as we mentioned in Chapter 4, it eventually calls the security manager, which calls the access controller. [2] Well show this example and class loaders to implement it in Chapter 6. Figure 5−2. A stack with multiple nonsystem protection domains In this example, the access controller first checks the protection domain for the Network class to see if a class loaded from http:network.xyz.com is allowed to connect to the socket. If that succeeds, it then checks the protection domain of the PayrollApp class to see if a class loaded from http:hr.xyz.com is allowed to connect to the socket. Only if both code sources are granted permission in the policy file either individually or via an entry that does not specify a code base at all does the checkPermission method succeed. Whether or not this is the appropriate behavior depends upon your intent. Lets say that the policy file for the payroll application specifies that classes with a code base of http:network.xyz.com are allowed to create sockets but that no other protection domains other than the system protection domain, of course are granted that permission. That leads to the situation where a class from the network services department might not be able to open a socket even though it has that permission in the file: if there is any class in the HR protection domain on the stack, the operation will fail. All classes on the stack must have permission for an operation to succeed. Often, however, you want a class to be temporarily given the ability to perform an action on behalf of a class that might not normally have that ability. In this case, we might want to establish a policy where the classes from the HR department cannot create a socket directly but where they can call classes from the network services department that can create a socket. [3] In this case, you want to tell the access controller to grant temporarily the permissions of the network services department to any methods that it might call within the current thread. [3] Consider this in terms of writing a file: an applet might not be able to write a file, but it can call a method of the SDK to play audio data −− which means the SDK class must write to the audio device file. That facility is possible with these methods of the access controller class: public static Object doPrivilegedPrivilegedAction pa public static Object doPrivilegedPrivilegedExceptionAction pae public static Object doPrivilegedPrivilegedExceptionAction action, AccessControlContext context Execute the run method on any given object, temporarily granting its permission to any protection domains below it on the stack. In the second case, if the embedded run method throws an exception, the doPrivileged method will throw a PrivilegedActionException . The PrivilegedAction and PrivilegedExceptionAction interfaces contain a single method: public Object run Run the target code, which will have the permissions of the calling class. The difference between the two interfaces is that the run method in the PrivilegedExceptionAction interface may throw an arbitrary exception. Note the unfortunate overloading between this method and the run method of the Thread class and Runnable interface, which return void ; a class cannot implement both the Runnable and PrivilegedAction interfaces. The PrivilegedActionException class is a standard exception, so you must always be prepared to catch it when using the doPrivileged method. If the embedded run method does throw an exception, that exception will be wrapped into the PrivilegedActionException , where it may be retrieved with this call: public Exception getException Return the exception that was originally thrown to cause the PrivilegedActionException to be thrown. Lets see how all of this might work with our network monitor example: package javasec.samples.ch05; import java.net.; import java.io.; import java.security.; public class NetworkMonitor { public NetworkMonitor { try { This class is used by the doPrivileged method to open a socket class doSocket implements PrivilegedExceptionAction { public Object run throws UnknownHostException, IOException { return new Socketnet.xyz.com, 4000; } }; doSocket ds = new doSocket ; Socket s = Socket AccessController.doPrivilegedds; } catch PrivilegedActionException pae { Exception e = pae.getException ; if e instanceof UnknownHostException { process host exception } else if e instanceof IOException { process IOException } else { e must be a runtime exception throw RuntimeException e; } } } } Two points are noteworthy here. First, the code that needs to be executed with the privileges of the NetworkMonitor class has been encapsulated into a new class −− the inner doSocket class. 94