Spec-Zone .ru
спецификации, руководства, описания, API
v
Previous Tutorial Tutorials Introduction and TOC Next Tutorial Feedback

JAAS Authorization



This tutorial expands the program and policy file developed in the JAAS Authentication tutorial to demonstrate the JAAS authorization component, which ensures the authenticated caller has the access control rights (permissions) required to do subsequent security-sensitive operations. Since the authorization component requires that the user authentication first be completed, please read the JAAS Authentication tutorial first if you have not already done so.

The rest of this tutorial consists of the following sections:

If you want to first see the tutorial code in action, you can skip directly to Running the Authorization Tutorial Code and then go back to the other sections to learn more.

What is JAAS Authorization?

JAAS authorization extends the existing Java security architecture that uses a security policy to specify what access rights are granted to executing code. That architecture, introduced in the Java 2 platform, is code-centric. That is, the permissions are granted based on code characteristics: where the code is coming from and whether it is digitally signed and if so by whom. We saw an example of this in the jaasacn.policy file used in the JAAS Authentication tutorial. That file contains the following:

grant codebase "file:./JaasAcn.jar" {
   permission javax.security.auth.AuthPermission 
                    "createLoginContext.JaasSample";
};

This grants the code in the JaasAcn.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.)

JAAS authorization augments the existing code-centric access controls with new user-centric access controls. Permissions can be granted based not just on what code is running but also on who is running it.

When an application uses JAAS authentication to authenticate the user (or other entity such as a service), a Subject is created as a result. The purpose of the Subject is to represent the authenticated user. A Subject is comprised of a set of Principals, where each Principal represents an identity for that user. For example, a Subject could have a name Principal ("Susan Smith") and a Social Security Number Principal ("987-65-4321"), thereby distinguishing this Subject from other Subjects.

Permissions can be granted in the policy to specific Principals. After the user has been authenticated, the application can associate the Subject with the current access control context. For each subsequent security-checked operation, (a local file access, for example), the Java runtime will automatically determine whether the policy grants the required permission only to a specific Principal and if so, the operation will be allowed only if the Subject associated with the access control context contains the designated Principal.

How is JAAS Authorization Performed?

To make JAAS authorization take place, the following is required:

How Do You Make Principal-Based Policy File Statements?

Policy file grant statements can now optionally include one or more Principal fields. Inclusion of a Principal field indicates that the user or other entity represented by the specified Principal, executing the specified code, has the designated permissions.

Thus, the basic format of a grant statement is now

grant <signer(s) field>, <codeBase URL> 
  <Principal field(s)> {
    permission perm_class_name "target_name", "action";
    ....
    permission perm_class_name "target_name", "action";
  };
where each of the signer, codeBase and Principal fields is optional and the order between the fields doesn't matter.

A Principal field looks like the following:

Principal Principal_class "principal_name"

That is, it is the word "Principal" (where case doesn't matter) followed by the (fully qualified) name of a Principal class and a principal name.

A Principal class is a class that implements the java.security.Principal interface. All Principal objects have an associated name that can be obtained by calling their getName method. The format used for the name is dependent on each Principal implementation.

The type of Principal placed in the Subject created by the Kerberos authentication mechanism used by this tutorial is javax.security.auth.kerberos.KerberosPrincipal, so that is what should be used as the Principal_class part of our grant statement's Principal designation. User names for KerberosPrincipals are of the form "name@realm". Thus, if the user name is "mjones" and the realm is "KRBNT-OPS.ABC.COM", the full principal_name designation to use in the grant statement is "mjones@KRBNT-OPS.ABC.COM".

It is possible to include more than one Principal field in a grant statement. If multiple Principal fields are specified, then the permissions in that grant statement are granted only if the Subject associated with the current access control context contains all of those Principals.

To grant the same set of permissions to different Principals, create multiple grant statements where each lists the permissions and contains a single Principal field designating one of the Principals.

The policy file for this tutorial includes one grant statement with a Principal field:

grant codebase "file:./SampleAction.jar",
    Principal javax.security.auth.kerberos.KerberosPrincipal 
        "your_user_name@your_realm"  {

   permission java.util.PropertyPermission "java.home", "read";
   permission java.util.PropertyPermission "user.home", "read";
   permission java.io.FilePermission "foo.txt", "read";
};
where you substitute your Kerberos user name (complete with "@" and realm) for "your_user_name@your_realm".

This specifies that the indicated permissions are granted to the specified principal executing the code in SampleAction.jar.

How Do You Associate a Subject with an Access Control Context?

To create and associate a Subject with an access control context, you need the following:

The Authorization Tutorial Code

The code for this tutorial consists of two files:

JaasAzn.java

JaasAzn.java is exactly the same as the JaasAcn.java code used in the previous tutorial except with three statements added at the end of the main method, after the authentication is done. These statements result in (1) association of a Subject representing the authenticated user with the current access control context and (2) execution of the code in the run method of SampleAction. Associating the Subject with the access control context enables security-sensitive operations in the SampleAction run method (and any code it invokes directly or indirectly) to be executed if a Principal representing the authenticated user is granted the required permissions in the current policy.

Like JaasAcn.java, JaasAzn.java instantiates a LoginContext lc and calls its login method to perform the authentication. If successful, the authenticated Subject (which includes a Principal representing the user) is obtained by calling the LoginContext's getSubject method:

Subject mySubject = lc.getSubject();

The main method then calls Subject.doAsPrivileged, passing it the authenticated Subject mySubject, a PrivilegedAction (SampleAction) and a null AccessControlContext, as described in the following.

The SampleAction class is instantiated via the following:

PrivilegedAction action = new SampleAction();

The call to Subject.doAsPrivileged is performed via:

Subject.doAsPrivileged(mySubject, action, null);

The doAsPrivileged method invokes execution of the run method in the PrivilegedAction action (SampleAction) to initiate execution of the rest of the code, which is considered to be executed on behalf of the Subject mySubject.

Passing null as the AccessControlContext (third) argument to doAsPrivileged indicates that mySubject should be associated with a new empty AccessControlContext. The result is that security checks occurring during execution of SampleAction will only require permissions for the SampleAction code itself (or other code it invokes), running as mySubject. Note that the caller of doAsPrivileged (and the callers on the execution stack at the time doAsPrivileged was called) do not require any permissions while the action executes.

SampleAction.java

SampleAction.java contains the SampleAction class. This class implements java.security.PrivilegedAction and has a run method that contains all the code we want to be executed as the Subject mySubject. For this tutorial, we will perform three operations, each of which cannot be done unless code has been granted required permissions. We will:

Here is the code:

import java.io.File;
import java.security.PrivilegedAction;

public class SampleAction implements PrivilegedAction {

  public Object run() {

    System.out.println("\nYour java.home property value is: "
                + System.getProperty("java.home"));

    System.out.println("\nYour user.home property value is: "
                + System.getProperty("user.home"));

    File f = new File("foo.txt");
    System.out.print("\nfoo.txt does ");
    if (!f.exists())
        System.out.print("not ");
    System.out.println("exist in the current working directory.");
    return null;
  }
}

The Login Configuration File

The login configuration file used for this tutorial can be exactly the same as that used by the JAAS Authentication tutorial. Thus we can use jaas.conf, which contains just one entry:

JaasSample {
  com.sun.security.auth.module.Krb5LoginModule required;
};

This entry is named "JaasSample" and that is the name that both our tutorial applications JaasAcn and JaasAzn use to refer to it. The entry specifies that the LoginModule to be used to do the user authentication is the Krb5LoginModule in the com.sun.security.auth.module package and that this Krb5LoginModule is required to "succeed" in order for authentication to be considered successful. The Krb5LoginModule succeeds only if the name and password supplied by the user are successfully used to log the user into the Kerberos KDC.

The Policy File

This authorization tutorial contains two classes, JaasAzn and SampleAction. The code in each class contains some security-sensitive operations and thus relevant permissions are required in a policy file in order for the operations to be executed.

Permissions Required by JaasAzn

The main method of the JaasAzn class does two operations for which permissions are required. It

The LoginContext creation is exactly the same as was done in the authentication tutorial, and it thus needs the same javax.security.auth.AuthPermission permission with target "createLoginContext.JaasSample".

In order to call the doAsPrivileged method of the Subject class, you need to have a javax.security.auth.AuthPermission with target "doAsPrivileged".

Assuming the JaasAzn class is placed in a JAR file named JaasAzn.jar, these permissions can be granted to the JaasAzn code via the following grant statement in the policy file:

grant codebase "file:./JaasAzn.jar" {
   permission javax.security.auth.AuthPermission 
                    "createLoginContext.JaasSample";
   permission javax.security.auth.AuthPermission "doAsPrivileged";
};

Permissions Required by SampleAction

The SampleAction code does three operations for which permissions are required. It

The permissions required for these operations are the following:

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

We need to grant these permissions to the code in SampleAction.class, which we will place in a JAR file named SampleAction.jar. However, for this particular grant statement we want to grant the permissions not just to the code but to a specific user executing the code, to demonstrate how to restrict access to a particular user.

Thus, as explained in How Do You Make Principal-Based Policy File Statements?, our grant statement looks like the following:

grant codebase "file:./SampleAction.jar",
    Principal javax.security.auth.kerberos.KerberosPrincipal 
        "your_user_name@your_realm"  {

   permission java.util.PropertyPermission "java.home", "read";
   permission java.util.PropertyPermission "user.home", "read";
   permission java.io.FilePermission "foo.txt", "read";
};
You substitute your Kerberos user name (complete with "@" and realm) for "your_user_name@your_realm". For example, if your user name is "mjones" and your realm is "KRBNT-OPERATIONS.ABC.COM", you would use "mjones@KRBNT-OPERATIONS.ABC.COM" (complete with the quotes).

The Full Policy File

The full policy file is jaasazn.policy.

Running the Authorization Tutorial Code

To execute our JAAS authorization tutorial code, all you have to do is

  1. Place the following files into a directory:

  2. Replace "your_user_name@your_realm" in jaasazn.policy with your user name and realm.

  3. Compile SampleAction.java and JaasAzn.java:
    javac SampleAction.java JaasAzn.java
    
  4. Create a JAR file named JaasAzn.jar containing JaasAzn.class:
    jar -cvf JaasAzn.jar JaasAzn.class
    
  5. Create a JAR file named SampleAction.jar containing SampleAction.class:
    jar -cvf SampleAction.jar SampleAction.class
    
  6. Execute the JaasAzn application, specifying

    1. by an appropriate -classpath clause that classes should be searched for in the JaasAzn.jar and SampleAction.jar JAR files,

    2. by -Djava.security.manager that a security manager should be installed,

    3. by -Djava.security.krb5.realm=<your_realm> that your Kerberos realm is the one specified.

    4. by -Djava.security.krb5.kdc=<your_kdc> that your Kerberos KDC is the one specified.

    5. by -Djava.security.policy=jaasazn.policy that the policy file to be used is jaasazn.policy, and

    6. by -Djava.security.auth.login.config=jaas.conf that the login configuration file to be used is jaas.conf.

    Below are the full commands to use for both Microsoft Windows and Unix systems. The only difference is that on Windows systems you use semicolons to separate classpath items, while you use colons for that purpose on Unix systems. Be sure to replace <your_realm> with your Kerberos realm, and <your_kdc> with your Kerberos KDC.

    Here is the full command for Windows systems:

    java -classpath JaasAzn.jar;SampleAction.jar 
     -Djava.security.manager 
     -Djava.security.krb5.realm=<your_realm> 
     -Djava.security.krb5.kdc=<your_kdc> 
     -Djava.security.policy=jaasazn.policy 
     -Djava.security.auth.login.config=jaas.conf JaasAzn
    

    Here is the full command for UNIX systems:

    java -classpath JaasAzn.jar:SampleAction.jar 
     -Djava.security.manager 
     -Djava.security.krb5.realm=<your_realm> 
     -Djava.security.krb5.kdc=<your_kdc> 
     -Djava.security.policy=jaasazn.policy 
     -Djava.security.auth.login.config=jaas.conf JaasAzn
    

    Type the full command on one line. Multiple lines are used here for legibility. If the command is too long for your system, you may need to place it in a .bat file (for Windows) or a .sh file (for UNIX) and then run that file to execute the command.

    You will be prompted for your Kerberos user name and password, and the underlying Kerberos authentication mechanism specified in the login configuration file will log you into Kerberos. If your login is successful, you will see the message "Authentication succeeded!" and if not, you will see "Authentication Failed."

    For login troubleshooting suggestions, see Troubleshooting.

    Once authentication is successfully completed, the rest of the program (in SampleAction) will be executed on behalf of you, the user, requiring you to have been granted appropriate permissions. The jaasazn.policy policy file grants you the required permissions, so you will see a display of the values of your java.home and user.home system properties and a statement as to whether or not you have a file named foo.txt in the current directory.



Previous Tutorial Tutorials Introduction and TOC Next Tutorial Feedback