Java Institute DreamsCity 2000
Welcome to DreamsCity
Return to Java Institute

POLICIES AND THE POLICY FILE

What JDK(tm) 1.1 needed was a security system that was declarative 
instead of procedural; in other words, a system where application 
developers and system administrators describe what security 
settings they want instead of how to implement them.
  

JDK(tm) 1.2 and later provide declarative, policy-based security 
through a new class java.security.AccessController. 
AccessController and related classes build on the pre-existing 
SecurityManager. You can still write your own security manager, 
but if you choose to rely on the new, policy-based security, 
you do not have to write any code. Starting with JDK 1.2, 
SecurityManager is a concrete class that delegates to the 
AccessController to implement a fine-grained, context-based 
security policy. Sun Microsystems provides a reference 
implementation of this policy that is controlled by a text file 
called the policy file.
  

To see a policy file in use, examine the following variation of
the TestSecurityManager class:


import java.io.*;

public class TestSecurityManager {

    public static void writeFile(String name) throws IOException {
        System.out.println("Writing to file " + name);
        FileOutputStream fos = new FileOutputStream(name);
        file://write something here...
        fos.close();
    }
    
    public static void main(String[] args) throws IOException {
        writeFile("temp");
        writeFile("other");
    }
}

This version of the class is different in that is does not call 
System.setSecurityManager. So, the class should run without 
security checks and write to both the "temp" and "other" files. 
To enable 1.2 security, you can either use setSecurityManager 
to install an instance of the SecurityManager class, or specify 
the following property on the command line:

java -Djava.security.manager TestSecurityManager

By default, the permissions granted to your local code are minimal.
So you should see an AccessControlException when trying to access 
the"temp" file: 

java.security.AccessControlException: access denied 
        (java.io.FilePermission temp write)
        
In order to enable writing to the temp file, you need to specify a 
policy in a policy file, which might look like this: 

file://file my.policy
grant {
    permission java.io.FilePermission "temp", "write";
};

You can instruct the virtual machine to use this policy file by
specifying the java.security.policy property:

java -Djava.security.manager 
    -Djava.security.policy=my.policy
    TestSecurityManager

With this command line, you should be able to write to the "temp" 
file, but not to the "other" file. Notice that this new solution 
provides the same capability as the custom TempfileSecurityManager 
class. However, you didn't have to write any Java code to use the 
policy file. The only work was making the correct settings in the 
policy file and on the command line.  While not foolproof, this 
declarative approach is far less prone to error than coding it 
yourself.  

The simple example above only begins to show the capabilities of 
the policy file. More generally, the syntax of a grant block in 
a policy file looks like this: 

grant [codeBase "URL"] {
    permission permissionClassName "target", "action";
    //...
};

JDK 1.2 includes permission classes for all of the security hooks 
in the virtual machine. So, for example, you could enable 
connecting to any machine's HTTP port with the following entry:

grant {
    permission java.io.SocketPermission "*:80", "connect";
};

The asterisk in the target string "*:80" is a wildcard for the 
machine address, so the connect action is allowed to target port 
80 of any machine.  

By default, grant entries apply to all the classes running in the 
JVM. As mentioned before, it is important to have a way to divide 
classes into different protection domains, each with their 
own set of permissions. The optional codeBase field accomplishes 
this by limiting the grant to classes loaded from a specific URL. 
Consider the following policy file:

grant codeBase "file:." {
    permission java.security.AllPermission;
}
grant codeBase "http://www.develop.com/TrustWorthyApplets/" {
    permission java.io.SocketPermission "*:80", "connect";
}

The first grant entry uses a file URL to give classes from the 
current directory the special permission "AllPermission." This 
permission basically disables security checks, and is useful only 
for very trusted code. In this example the trusted code is in the 
current directory (presumably you wrote that code yourself). The 
second entry uses an HTTP URL to specify that applets downloaded 
from a specific website can connect to any machine's HTTP port.  
The codeBase field makes it easy to configure fine-grained access 
control, without writing any code. This flexible control is 
essential for distributed systems built with higher level 
technologies such as RMI, JINI, or EJB.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The JDK 1.2 security architecture supports several interesting 
capabilities not covered here, including digital signing, custom 
permissions, custom policy implementations, and privileged scopes.  
For more information on these security features, examine the 
security documentation at: 

http://java.sun.com/j2se/1.3/docs/guide/security/index.html

Java supports user-based security through the Java 
Authentication and Authorization Service (JAAS). For 
information about JAAS, see:

http://java.sun.com/products/jaas/

For a comprehensive description of security in the Java 2 
Platform, see the book "Inside Java 2 Platform Security: 
Architecture, API Design, and Implementation" by Li Gong
(http://java.sun.com/docs/books/security/index.html).


Any comments? email to:
richard@dreamscity.net