Sun Java System Access Manager 7 2005Q4 Developer's Guide

Chapter 7 Using the JAAS Authorization Framework

Previous versions of Access Manager (Identity Server 6.0 and 6.1) provided custom policy APIs to define and evaluate access policies. This model provided centralized management of policies in its own policy store, the Sun ONE or Java Enterprise System (JES) Directory Server. In Sun JavaTM System Access Manager 6.2 and beyond, the authorization segment of the Java Authentication and Authorization Service (JAAS) framework is added to the original model. This model is based on JAAS 1.0 and Java 2 Platform, Standard Edition (J2SE) 1.3.1.

Access Manager now bridges the gap between J2SE and Access Manager APIs. In this framework, Access Manager maps its private APIs to JAAS interfaces. This makes it possible for you to use the JAAS interface to access the Access Manager policy framework.

The topics covered in this chapter are:

Overview of JAAS Authorization

JAAS is a set of APIs that enable services to authenticate and enforce access controls upon users. It implements a Java technology version of the standard Pluggable Authentication Module (PAM) framework, and supports user-based authorization. JAAS authorization extends the Java security architecture which uses a security policy to specify what access rights are granted to executing code. That architecture, introduced in the Java 2 platform, is code-based. The permissions are granted based on code characteristics such as where the code is coming from, whether it is digitally signed, and if so, the identity of the signer.

Overview of JAAS Authorization illustrates a Java security policy. This grants the code in the am_services.jar file, located in the current directory, the specified permission. No signer is specified, so it doesn’t matter whether the code is signed or not.


Example 7–1 Example of a Java Security Policy


grant codebase Cfile:./am_services.jar" {
            permission javax.security.auth.AuthPermission
                             "createLoginContext.AMLoginContext";
         };


         

JAAS authorization adds user centric access control that applies control based on what code is running as well as on who is running it.

By default, JAAS comes with a reference implementation of Policy (com.sun.security.auth.PolicyFile) which is file-based. This implementation parses the Java.policy file ${java.home}/lib/security directory and uses that to direct the associations of permissions to code. You can change the pointer to some other PolicyFile implementation or use a combination of files. By default, two files are consulted to evaluate policy. One is com.sun.security.auth.PolicyFile, mentioned above, and the other is .java.policy as defined in user’s home directory.

To make JAAS authorization take place, include a Principal field in the grant statement or statements in your policy file. A Principal field indicates which user executing the code is allowed the designated permissions. The Policy file grant statements can now optionally include one or more Principal fields. Including Principal field in the grant statement indicates that the user represented by the specified Principal, who is executing the specified code, has the designated permissions. See the Principal field example in Overview of JAAS Authorization.


Example 7–2 A Policy File Grant Statement


              grant   codebase "file:./am_services.jar",

                      Principal javax.security.auth.XXXprincipal


                      "your_user_name@your_domain"  {


                 permission java.util.PropertyPermission "java.home", "read";
                 permission java.util.PropertyPermission "user.home", "read";
                 permission java.io.FilePermission "foo.txt", "read";
              };


         

How Policy Enforcement Works

The Java 2 runtime enforces access controls via the java.lang.SecurityManager , which is consulted any time untrusted code attempts to perform a sensitive operation (accesses to the local file system, for example). To determine whether the code has sufficient permissions, the SecurityManager implementation delegates responsibility to the java.security.AccessController, which first obtains an image of the current AccessControlContext, and then ensures that the retrieved AccessControlContext contains sufficient permissions for the operation to be permitted.

JAAS supplements this architecture by providing the method Subject.doAs to dynamically associate an authenticated subject with the current AccessControlContext. As subsequent access control checks are made, the AccessController can base its decisions upon both the executing code itself, and upon the principals associated with the subject. Access Manager provides support for JAAS authentication, which results in the population of the subject with Principals that represents the user.


Example 7–3 The Subject.doAs Method


public final class Subject {
                ...
                // associate the subject with the current
                // AccessControlContext and execute the action
                public static Object doAs(Subject s,
                                java.security.PrivilegedAction action) { }
            }

            

To illustrate a usage scenario for the doAs method, consider a service that authenticates a remote subject, and then performs some work on behalf of that subject. For security reasons, the server should run in an AccessControlContext bound by the subject’s permissions. Using JAAS, the server can ensure this by preparing the work to be performed as a java.security.PrivilegedAction . Then, by invoking the doAs method, the server provides both the authenticated subject and the prepared PrivilegedAction. The doAs implementation associates the subject with the current AccessControlContext and then executes the action. When security checks occur during execution, the Java 2 SecurityManager queries the JAAS policy, updates the current AccessControlContext with the permissions granted to the subject and the executing codesource, and then performs its regular permission checks. When the action is completed, the doAs method removes the subject from the current AccessControlContext, and returns the result back to the caller. How Policy Enforcement Works illustrates this flow.


Example 7–4 Sample Code for Subject.doAS


public static void main(String[] args) {
        try {
            // Create an SSOToken
            AuthContext ac = new AuthContext("dc=iplanet,dc=com");
            ac.login();
            Callback[] callbacks = null;
            if (ac.hasMoreRequirements()) {
                callbacks = ac.getRequirements();

                if (callbacks != null) {
                    try {
                        addLoginCallbackMessage(callbacks); 
						// this method sets appropriate responses in the callbacks.
                        ac.submitRequirements(callbacks);
                    } catch (Exception e) { }
                }
            }
            if (ac.getStatus() == AuthContext.Status.SUCCESS) {
                  Subject subject = ac.getSubject(); 
						// get the authenticated subject
                  FilePermission perm = new FilePermission("/tmp/test","read");

                      Subject.doAs(subject, new PrivilegedExceptionAction() {
                      /* above statement means execute  run() method of the
								 /* Class PrivilegedExceptionAction()
                          as the specified subject */
                      public Object run() throws IOException  {
                          // if the above run()  was not throwing Exception 
									/* could have created an instance of PrivilegedAction
                          // instead of  PrivilegedExceptionAction here
                          AccessController.checkPermission(perm);
                            File = new File("/tmp/test");
                            return null;
                      }
                 });
             }
   }


            

In this example, the AccessController is checking the application’s current policy implementation. If any permission defined in the policy file implies the requested permission, the method will simply return; otherwise an AccessControlException will be thrown. The check is actually redundant in this example, because the constructor for the default File implementation performs the same check. The sample is meant to illustrate the flow.

How the JS2E Access Controller Works

AccessController works with the java.security.Policy implementation to securely process application requests. In JS2E, a typical checkPermission(Permission p) method call on the AccessController class might result in the following sequence:

  1. The AccessController invokes the getPermisisons() method of the javax.security.auth policy passing in the subject and the code source.

  2. The getPermissions() method returns a PermissionCollection class instance, which represents a collection of same types of permissions.

  3. The elements() method of the returned PermissionCollection gets called, which returns an enumeration of the permissions held in this PermissionCollection.

  4. For each of the permissions returned in the enumeration (in step 3), the perm.newPermissionCollection() method gets called to obtain the PermissionCollection used to store the permission.

  5. PermissionCollection.add(perm) gets called by the J2SE internal code to store the permission in its PermissionCollection.

  6. The AccessController calls the implies(Permission p) method of the PermissionCollection returned in step 2.

  7. Once the implies() of PermissionCollection is called, it in turn triggers the calling of implies(Permission p) of the individual permission objects contained in the PermissionCollection . These methods return true if the current permission object in the collection implies the specified permission; the methods return false the current permission object in the collection does not imply the specified permission. This outcome is implementation dependent and can be changed.

JAAS Authorization in Access Manager

Access Manager provides a custom implementation of the JAAS javax.security.auth.Policy . The customized implementation leverages the J2SE access controller and security manager to provide policy evaluation for all Access Manager related permissions. The customized implementation also falls back on the J2SE default Policy implementation com.sun.security.auth.PolicyFile for access to system level resources. Access Manager policy does not control access to com.sun.security.auth.PolicyFile.

Access Manager uses both JAAS and J2SE’s file-based policy for all the resources for which Access Manager does not provide access control. For Access Manager resources such as URLs and so forth, new policy and permissions are defined. This model leverages the best of JAAS and the best of J2SE in one solution. It uses the JAAS framework for its default access control where needed, and then enhances the framework to incorporate the Access Manager policy evaluation. In this way, you can use the Access Manager policy implementation to make policy evaluations pertaining to Access Manager policies, but revert back to the default method of controlling access to resources not under Access Manager control.

Custom APIs

Access Manager provides the following custom APIs:.

For a comprehensive listing of related APIs, see the Javadoc in the following directory: AccessManager-base/SUNWam/docs.

User Interface

The user interface for entering permissions and policy is the Access Manager administration console which works with the policy administration API. Once the policy is defined, the evaluation is done using the J2SE architecture and enhanced policy implementation.

ISPermission covers the case when additional policy services are defined and imported, provided they only have boolean action values. In fact boolean evaluation is all that can be done using JAAS since JAAS permissions have a boolean result.

Enabling the JAAS Authorization Framework

You enable the JAAS authorization framework by resetting policy. Use the Policy.setPolicy(Policy) API to reset policy during run time. In Enabling the JAAS Authorization Framework, Policy.setPolicy(com.sun.identity.policy.jaas.ISPolicy) resets the policy. In this example, the client application wants to use JAAS authorization API to communicate with the Access Manger and to perform policy evaluation. Access Manager provides the support needed to use Access Manager policy so that policy can be defined through the new ISPermission.


Example 7–5 Sample JAAS Authorization Code


 public static void main(String[] args) {
        try {
            // Create an SSOToken

           AuthContext ac = new AuthContext("dc=iplanet,dc=com");
            ac.login();
            Callback[] callbacks = null;
            if (ac.hasMoreRequirements()) {
                callbacks = ac.getRequirements();

                if (callbacks != null) {
                    try {
                        addLoginCallbackMessage(callbacks); 
					// this method sets appropriate responses in the callbacks.
                        ac.submitRequirements(callbacks);
                    } catch (Exception e) { }
                }
            }
            if (ac.getStatus() == AuthContext.Status.SUCCESS) {
                  Subject subject = ac.getSubject();
							// get the authenticated subject

                    Policy.setPolicy(new ISPolicy()); // change the policy to  our own Policy


                    ISPermission perm = new ("iPlanetAMWebAgentService",

                        "http://www.sun.com:80", "GET");
                  Subject.doAs(subject, new PrivilegedExceptionAction() {
                      /* above statement means execute  run() method of the
								 /* Class PrivilegedExceptionAction()
                          as the specified subject */
                      public Object run() throws Exception {
                          AccessController.checkPermission(perm);
                            // the above will return quietly if the Permission
										 //  has been granted
                            // else will throw access denied
                            // Exception, so if the above highlighed ISPermission
										 // had not been granted, this return null;
                      }
                 });
             }
   }