The Access Controller

  

The history of the access controller started with Java 2 and provided the default implementation of the security manager. The class for implementing the access controller is java.security.AccessController . The constructor of the access controller is private so that it cannot be instantiated because the use of the class is dependent on its static methods like checkPermission ( ) . The checkPermission ( ) method checks the permission of an object. The permission is associated with a protection domain for each method on the stack. The protection domain is associated with a single grant entry. An example of a grant that would appear in a policy file can be seen in Listing 18-2.

Listing 18-2: Grant entry
start example
 grant {   permission java.util.PropertyPermission "java.version", "read"; }; 
end example
 

Listing 18-2 shows a basic grant entry in a policy file. Each grant entry has a set of permissions that it will apply to a protection domain. Each class with the protection domain will have the permission checked for each method on the stack. In this grant entry example, any class in the protection domain can have access to read the system property of the Java version number being used in the JRE. Each permission entry in the grant entry requires the Permission class type, in this case PropertyPermission , and the parameter and operation based on the permission type. For the property permission, the system property name of java.version and the read operation are acceptable.

There are always exceptions to the rules, and they must be accounted for in the protection domain. The issue could arise in the protection domain because only a class can go beyond what is defined in the grant entry. It might be necessary to bypass the grant entry in only one method while all the other methods follow the grant entry. An example comes from the KeyStore.java file that is distributed with the JDK 1.4. If the KeyStore type is not jks, then a get system property is performed to get the current keystore type. The reading of the keystore.type might not be set in the grant entry, so the privileged action demonstrated bypasses the security mechanism.

The doPrivileged ( ) methods on the AccessController can be used to perform specific actions as a privileged caller. When a checkPermission method does reach the privileged action with the doPrivileged method, the checkPermission will not check the permission of the privileged action. Privileged actions are bypassed from the checkPermission method and will not be denied access for any reason from an AccessController . Listing 18-3 shows an example of the doPrivileged action.

Listing 18-3: A doPrivileged action
start example
 public final static String getDefaultType() {  String kstype;  kstype = (String)AccessController.doPrivileged(new  PrivilegedAction()  {      public Object run() {   return Security.getProperty(KEYSTORE_TYPE);      }  });  if (kstype == null) {      kstype = "jks";  }  return kstype; } 
end example
 

The AccessController checks each of the threads in the current thread's given context. Each AccessController call checks a specific thread's context, not taking into account the parent thread. It would be a lot easier if the thread just inherited the parent's thread security context. Every time a new thread is created, the parent's security context is passed down to the newly created thread. To pass the parent's security context, the checkPermission ( ) method calls would have to take into consideration the parent's context. The AccessControlContext class takes into consideration both the parent's context and the current thread being executed.

The AccessControlContext 's checkPermission method is a transitive method in that it takes into account the parent's and even the grandparent's security context. The AccessControlContext takes into account the thread's current context, while the AccessControl class checks throughout the thread's current context. Using the same permission set during the thread's current context ensures that all the subsequent threads will have the same access control. However, the permission set should not be used when it is assumed that the permissions are not to be changed throughout the threads that are created from the application. The AccessControl class should be used if the threads that are created by the application have different access and permissions. To execute the AccessControlContext 's checkPermission method, the current context of the AccessControl can be returned with Listing 18-4.

Listing 18-4: Code fragment to get the context
start example
 AccessControlContext context = AccessController.getContext(); 
end example
 

The method in Listing 18-4 returns the current thread's context from the AccessController . Subsequent children threads can then use the returned AccessControlContext to perform a checkPermission on child threads that will use the same permission set. The AccessControlContext can be executed in more than one ProtectionDomain . A ProtectionDomain encapsulates the permission set with a single grant entry. The ProtectionDomain stores the permission set as a PermissionCollection object, the array of Principal objects, and the CodeSource object. The CodeSource is made up of the optional CodeBase entry and possibly many SignedBy entries. The CodeBase object encapsulates the code update location mapped in a URL. The SignedBy entries are an array of Certificate objects. The array of Principal objects are the users or groups that have access to the permissions. Figure 18-3 shows a diagram of the Protection Domain/grant entry.

click to expand
Figure 18-3: The Protection Domain

Guarded objects

The notion of an access controller is an object encapsulating access of resources of other objects in the current thread creating a new thread context. The access control context is an object that encapsulates access of resources of other objects throughout the thread context. The guarded object is used to protect the object from another object. There are three pieces to understanding the guarded object: the guard, the protected object, and the requesting object. The guarded object uses the java.security.GuardedObject class.

The constructor of the guarded object uses two parameters: the protected object and the guard. The protected object is the object that is being protected by the guard. The guard is a class from the Permission class such as the FilePermission class. The requesting object is the object that will try to access the protected object by calling the getObject ( ) method. The object that is created by a guarded object is constructed but cannot be retrieved until a getObject ( ) method is performed to retrieve the newly created object. When the getObject ( ) method is called, the guarded object performs a checkGuard ( ) operation against the guard and if the protected object can be accessed by the definition of the guard, then access is granted. Listing 18-5 demonstrates this functionality.

Listing 18-5: The RichGuard class: An example of a guarded object
start example
 package com.richware.chap18; import java.security.*; import java.io.*;     /**  * Class RichGuard  * Description: A custom demonstration of  * guarding an object. This code is the requestor.  *  * Copyright:    Copyright (c) 2002 Wiley Publishing, Inc.  * @author Rich Helton <rhelton@richware.com>  * @version 1.0    * DISCLAIMER: Please refer to the disclaimer at the beginning of this  book.   */ public class RichGuard {       /**    * Method main    * Description: The main driver to run the methods.    *    *    * @param args (no arguments presently).    *    */   public static void main(String args[]) {     try {       /*        * Combine the userdirectory + package name + input file        * to find the file and where its location should be        */       System.out.println("Starting RichGuard....");       String localDirectory  = System.getProperty("user.dir");       System.out.println("Changing directory to Chapter 11");        System.setProperty("user.dir",localDirectory +  "\com\richware\chap18\");       localDirectory  = System.getProperty("user.dir");       String localInputFile  = localDirectory + args[0];       System.out.println("Openining Chapter 14 plus the input file as an  argument: " + localInputFile);            /*        * Create the protected object        * as a FileInputStream object        */       FileInputStream protectedObject =         new FileInputStream(localInputFile);           /*        * Create the guard object        * as a FilePermission for        * what is needed to access the object.        */       FilePermission guard = new FilePermission(localInputFile,                                                 "read");           /*        * Create the guarded object        * which is an association between the        * requestor, guard and protected object        */       GuardedObject guardedObject =         new GuardedObject(protectedObject, guard);           /*        * get the object so this is        * the requestor object        * this will call the checkGuard        * and Permission.checkPermission()        */       Object o = guardedObject.getObject();           System.out.println("Got access to object");           /*        *   catches.        */     } catch (AccessControlException e) {       e.printStackTrace();     } catch (Exception e) {       e.printStackTrace();     }   } } 
end example
 

The guarded object uses the FilePermission object as the guard that is set for read access on the temp.txt file. If the application doesn't have read permission on temp.txt , then a SecurityException is thrown. The permission will be validated with a defined security manager that will look up the permission set through the protection domain.

If no security manager is present, the SecurityException will not be thrown. The check for the permission will be called by the guard's Permission.checkGuard ( ) method during the requestor's call to the getObject ( ) method.

An example output looks like the following code fragment:

 >java com.richware.chap18.RichGuard temp.txt Starting RichGuard.... Changing directory to Chapter 11 Opening Chapter 14 plus the input file as an argument:  C:\RICH\com\richware\chap18\temp.txt Got access to object 

The purpose of guarded objects is slightly different from that of the access controller, but it does make significant use of the Permission class, security manager, and protection domain just as the access controller does. The concept of the guarded object is to validate the permission of the protected object with the protection domain before retrieving the object in the requesting object. The requesting object cannot access the object itself until the defined protection domain grants access.

If a security manager defines no protection domain, then permission is granted. The biggest difference between the access controller and the guarded object is that in the guarded object, the access is checked outside of the defined or guarded object; whereas in the access controller, the access method checkRead ( ) is performed in the FileInputStream object when there is an attempt to read the file.

The signed object

Another concept that was introduced in Java 2 is the concept of a signed object. A signed object is used to apply a digital signature to a serialized object when it is written to disk. The digital signature is used to check the integrity of the saved serialized object to ensure that no one has tampered with the serialized object. The digital signature of the serialized object is signed with a private key and verified with the matching public key.

A serializable object uses the readObject ( ) and writeObject ( ) methods to read and write the object to Java streams using the java.io.Serializable interface. The serializable object is passed in the creation of the java.security.SignedObject along with the private key and signature algorithm.

When the creation of the SignedObject is executed, the writeObject ( ) method of the serializable object is encapsulated internally to the signed object. When the verify ( ) method is executed, the object is read back out and if the verification succeeds, the object can be retrieved with the getObject ( ) method. Listing 18-6 demonstrates the functionality just described.

Listing 18-6: The RichSign class: A signed object example
start example
 package com.richware.chap18; import java.security.*; import java.io.*;     /**  * Class RichSign   * Description: A custom demonstration of  * signing an object.  *  * Copyright:    Copyright (c) 2002 Wiley Publishing, Inc.  * @author Rich Helton <rhelton@richware.com>  * @version 1.0   * DISCLAIMER: Please refer to the disclaimer at the beginning of this book.   */ public class RichSign {       /**    * Method main    * Description: The main driver to run the methods.    *    *    * @param args (no arguments presently).    *    */   public static void main(String args[]) {     try {        System.out.println("Starting RichSign....");       /*        * Create the Serialized object        */       String str = "I am verified";           /*        * Create the KeyPair        */       KeyPairGenerator keyGen =         KeyPairGenerator.getInstance("DSA");           /*        * Create the signature        */       Signature sign    = Signature.getInstance("SHA1withDSA");       KeyPair   keyPair = keyGen.generateKeyPair();       System.out.println("Creating signed object ...");           /*        * Create the Signed object        */       SignedObject so = new SignedObject(str,                                          keyPair.getPrivate(),                                          sign);           System.out.println("\nVerifying signature ...");           /*        * verify the Signed object        * print the results        */       if (so.verify(keyPair.getPublic(), sign)) {         System.out.println(so.getObject());       } else {         System.out.println("Signature NOT verified!");       }     } catch (Exception e) {       e.printStackTrace();     }   } } 
end example
 

An run of Listing 18-6 gives the following:

 >java com.richware.chap18.RichSign Starting RichSign.... Creating signed object ...     Verifying signature ...  I am verified 
  


Java Security Solutions
Java Security Solutions
ISBN: 0764549286
EAN: 2147483647
Year: 2001
Pages: 222

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net