# JAAS Authorization Tutorial

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:

- What is JAAS Authorization?

- How is JAAS Authorization Performed?

  - How Do You Make Principal-Based Policy File Statements?

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

- The Authorization Tutorial Code

- The Login Configuration File

- The Policy File

- Running the Authorization Tutorial Code

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 `sampleacn.policy` file used in the JAAS Authentication tutorial. That file contains the following:

> >     grant codebase "file:./SampleAcn.jar" {

> >        permission javax.security.auth.AuthPermission
> >                         "createLoginContext.Sample";
> >     };

> This grants the code in the `SampleAcn.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:

> - The user must be authenticated, as described in the JAAS Authentication tutorial.

> - Principal-based entries must be configured in the security policy.

> - The Subject that is the result of authentication must be associated with the current access control context.

> ### 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 basic authentication mechanism used by this tutorial is `SamplePrincipal`, so that is what should be used as the `Principal_class` part of our `grant` statement's Principal designation. User names for `SamplePrincipal`s are of the form "name", and the only user name accepted for this tutorial is "testUser", so the `principal_name` designation to use in the `grant` statement is "testUser".

> > 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 sample.principal.SamplePrincipal "testUser" {

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

> > This specifies that the indicated permissions are granted to the specified principal executing the code in `SampleAction.jar`. (Note: the SamplePrincipal class is in the `sample.principal` package.)

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

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

> > - The user must first be authenticated, as described in JAAS Authentication.

> > - The static `doAs` method from the Subject class must be called, passing it an authenticated Subject and a java.security.PrivilegedAction or java.security.PrivilegedExceptionAction. (See API for Privileged Blocks for a comparison of PrivilegedAction and PrivilegedExceptionAction.) The `doAs` method associates the provided Subject with the current access control context and then invokes the `run` method from the action. The `run` method implementation contains all the code to be executed as the specified Subject. The action thus executes as the specified Subject.

> >   The static `doAsPrivileged` method from the Subject class may be called instead of the `doAs` method, as will be done for this tutorial. In addition to the parameters passed to `doAs`, `doAsPrivileged` requires a third parameter: an AccessControlContext. Unlike `doAs`, which associates the provided Subject with the current access control context, `doAsPrivileged` associates the Subject with the provided access control context or with an empty access control context if the parameter passed in is `null`, as is the case for this tutorial. See doAs vs. doAsPrivileged in the JAAS Reference Guide for a comparison of those methods.

## The Authorization Tutorial Code

> The code for this tutorial consists of four files:

> - SampleAzn.java is exactly the same as the `SampleAcn.java` application file from the JAAS Authentication tutorial except for the additional code needed to call `Subject.doAsPrivileged`.

> - SampleAction.java contains the SampleAction class. This class implements PrivilegedAction and has a `run` method that contains all the code we want to be executed with Principal-based authorization checks.

> - SampleLoginModule.java is the class specified by the tutorial's login configuration file as the class implementing the desired underlying authentication. SampleLoginModule's user authentication consists of simply verifying that the name and password specified by the user have specific values. This class was also used by the JAAS Authentication tutorial and will not be discussed further here.

> - SamplePrincipal.java is a sample class implementing the java.security.Principal interface. It is used by SampleLoginModule. This class was also used by the JAAS Authentication tutorial and will not be discussed further here.

> The `SampleLoginModule.java` and `SamplePrincipal.java` files were also used in the JAAS Authentication tutorial, so they are not described further here. The other source files are described below.

> ### SampleAzn.java

> > Like SampleAcn, the SampleAzn class instantiates a LoginContext `lc` and calls its `login` method to perform the authentication. If successful, the authenticated Subject (which includes a SamplePrincipal representing the user) is obtained by calling the LoginContext's `getSubject` method:

> > >     Subject mySubject = lc.getSubject();

> > After providing the user some information about the Subject, such as which Principals it has, 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:

> > - Read and print the value of the `java.home` system property,

> > - Read and print the value of the `user.home` system property, and

> > - Determine whether or not a file named `foo.txt` exists in the current directory.

> > Here is the code:

> > >     package sample;

> > >     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 sample_jaas.config, which contains just one entry:

> >     Sample {
> >       sample.module.SampleLoginModule required debug=true;
> >     };

> This entry is named "Sample" and that is the name that both our tutorial applications `SampleAcn` and `SampleAzn` use to refer to it. The entry specifies that the LoginModule to be used to do the user authentication is the SampleLoginModule in the `sample.module` package and that this SampleLoginModule is required to "succeed" in order for authentication to be considered successful. The SampleLoginModule succeeds only if the name and password supplied by the user are the one it expects ("testUser" and "testPassword", respectively).

> The SampleLoginModule also defines a "debug" option that can be set to `true` as shown. If this option is set to `true,` SampleLoginModule outputs extra information about the progress of authentication.

## The Policy File

> The application for this authorization tutorial consists of two classes, `SampleAzn` 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.

> The LoginModule used by this tutorial, `SampleLoginModule`, also contains an operation requiring a permission.

> The permissions required by each of these classes are described below, followed by a link to the full policy file.

> ### Permissions Required by SampleAzn

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

> > - creates a LoginContext, and

> > - calls the `doAsPrivileged` static method of the Subject class.

> > 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.Sample`".

> > 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 `SampleAzn` class is placed in a JAR file named `SampleAzn.jar`, these permissions can be granted to the `SampleAzn` code via the following `grant` statement in the policy file:

> > >     grant codebase "file:./SampleAzn.jar" {
> > >        permission javax.security.auth.AuthPermission
> > >                         "createLoginContext.Sample";
> > >        permission javax.security.auth.AuthPermission "doAsPrivileged";
> > >     };

> ### Permissions Required by SampleAction

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

> > - reads the value of the "java.home" system property.

> > - reads the value of the "user.home" system property.

> > - checks to see whether or not a file named `foo.txt` exists in the current directory.

> > 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 sample.principal.SamplePrincipal "testUser" {

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

> ### Permissions Required by SampleLoginModule

> > The `SampleLoginModule` code does one operation for which permissions are required. It needs a `javax.security.auth.AuthPermission` with target "modifyPrincipals" in order to populate a Subject with a Principal. The grant statement is the following:

> > >     grant codebase "file:./SampleLM.jar" {
> > >         permission javax.security.auth.AuthPermission "modifyPrincipals";
> > >     };

> ### The Full Policy File

> > The full policy file is sampleazn.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:

>    - The sample_jaas.config login configuration file.
>    - The sampleazn.policy policy file.

> 2. Create a subdirectory named "sample" of that top-level directory, and place the following into it (note the SampleAzn and SampleAction classes are in a package named `sample`):

>    - The SampleAzn.java source file.
>    - The SampleAction.java source file.

> 3. Create a subdirectory of the "sample" directory and name it "module". Place the following into it (note the SampleLoginModule class is in a package named `sample.module`):

>    - the SampleLoginModule.java source file

> 4. Create another subdirectory of the "sample" directory and name it "principal". Place the following into it (note the SamplePrincipal class is in a package named `sample.principal`):

>    - the SamplePrincipal.java source file

> 5. While in the top-level directory, compile all the source files:

>    >     javac sample/SampleAction.java sample/SampleAzn.java
>    >     sample/module/SampleLoginModule.java sample/principal/SamplePrincipal.java

>    (Type all that on one line.)

> 6. Create a JAR file named `SampleAzn.jar` containing `SampleAzn.class` and `MyCallbackHandler.class` (Note the sources for both these classes are in `SampleAzn.java`):

>    >     jar -cvf SampleAzn.jar sample/SampleAzn.class
>    >     sample/MyCallbackHandler.class

>    (Type all that on one line.)

> 7. Create a JAR file named `SampleAction.jar` containing `SampleAction.class`:

>    >     jar -cvf SampleAction.jar sample/SampleAction.class

> 8. Create a JAR file containing `SampleLoginModule.class` and `SamplePrincipal.class`:

>    >     jar -cvf SampleLM.jar sample/module/SampleLoginModule.class
>    >     sample/principal/SamplePrincipal.class

> 9. Execute the `SampleAzn` application, specifying

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

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

>    3. by `-Djava.security.policy==sampleazn.policy` that the policy file to be used is `sampleazn.policy`, and

>    4. by `-Djava.security.auth.login.config==sample_jaas.config` that the login configuration file to be used is `sample_jaas.config`.

>    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.

>    Here is the full command for Windows systems:

>    >     java -classpath SampleAzn.jar;SampleAction.jar;SampleLM.jar
>    >      -Djava.security.manager
>    >      -Djava.security.policy==sampleazn.policy
>    >      -Djava.security.auth.login.config==sample_jaas.config sample.SampleAzn

>    Here is the full command for UNIX systems:

>    >     java -classpath SampleAzn.jar:SampleAction.jar:SampleLM.jar
>    >      -Djava.security.manager
>    >      -Djava.security.policy==sampleazn.policy
>    >      -Djava.security.auth.login.config==sample_jaas.config sample.SampleAzn

>    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 a user name and password (use "testUser" and "testPassword"), and the SampleLoginModule specified in the login configuration file will check the name and password. If your login is successful, you will see the message "Authentication succeeded!" and if not, you will see "Authentication failed:" followed by a reason for the failure.

>    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 `sampleazn.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.