The doAs methods

The following static methods may be called to perform an action as a particular Subject:

    public static Object 
        doAs(final Subject subject,
             final java.security.PrivilegedAction action);

    public static Object 
        doAs(final Subject subject,
             final java.security.PrivilegedExceptionAction action)
             throws java.security.PrivilegedActionException;

Both methods first associate the specified subject with the current Thread's AccessControlContext, and then execute the action. This achieves the effect of having the action run as the subject. The first method can throw runtime exceptions but normal execution has it returning an Object from the run method of its action argument. The second method behaves similarly except that it can throw a checked exception from its PrivilegedExceptionAction run method. An AuthPermission with target "doAs" is required to call the doAs methods.

Subject.doAs Example 1

Here is an example utilizing the first doAs method. Assume that someone named "Bob" has been authenticated by a LoginContext (see the LoginContext section) and as a result a Subject was populated with a Principal of class com.ibm.security.Principal, and that Principal has the name "BOB". Also assume that a SecurityManager has been installed, and that the following exists in the access control policy (see the Policy section for more details on the policy file).

    // grant "BOB" permission to read the file "foo.txt"
    grant Principal com.ibm.security.Principal "BOB" {
        permission java.io.FilePermission "foo.txt", "read";
    };

Here is the sample application code:

    class ExampleAction implements java.security.PrivilegedAction {
        public Object run() {
            java.io.File f = new java.io.File("foo.txt");

            // the following call invokes a security check
            if (f.exists()) {
                System.out.println("File foo.txt exists");
            }
            return null;
        }
    }

    public class Example1 {
        public static void main(String[] args) {

            // Authenticate the subject, "BOB".
            // This process is described in the
            // LoginContext section.
            
            Subject bob;
            // Set bob to the Subject created during the 
            // authentication process

            // perform "ExampleAction" as "BOB"
            Subject.doAs(bob, new ExampleAction());
        }
    }

During execution, ExampleAction will encounter a security check when it makes a call to f.exists(). However, since ExampleAction is running as "BOB", and the policy (described previously) grants the necessary FilePermission to "BOB", the ExampleAction will pass the security check.

Example 2 has the same scenario as Example 1.

Subject.doAs Example 2

    public class Example2 {
        // Example of using an anonymous action class.
        public static void main(String[] args) {
            // Authenticate the subject, "BOB".
            // This process is described in the
            // LoginContext.

            Subject bob;
            ...

            // perform "ExampleAction" as "BOB":
                Subject.doAs(bob, new ExampleAction() {
                public Object run() {
                    java.io.File f = new java.io.File("foo.txt");
                    if (f.exists()) {
                        System.out.println("File foo.txt exists.");
                    }
                    return null;
                }
            });
        }
    }

Both examples throw a SecurityException if the grant statement in the policy is altered (adding an incorrect CodeBase or changing the Principal to "MOE", for example), then a SecurityException will be thrown.

Since both examples perform the same function, there must be a reason to write code one way rather than the other. Example 1 may be easier to read for some programmers unfamiliar with anonymous classes. Also, the action class could be placed in a separate file with a unique CodeBase and then the permission grant could utilize this information. Example 2 is more compact and the action to be performed is easier to find since it is there in the doAs call.