JAAS Reference Guide (original) (raw)

Home Page

Java Authentication and Authorization Service (JAAS) Reference Guide

This guide covers the following topics:


Introduction

The Java Authentication and Authorization Service (JAAS) was introduced as an optional package (extension) to the Java 2 SDK, Standard Edition (J2SDK), v 1.3. JAAS was integrated into the J2SDK 1.4.

JAAS can be used for two purposes:

JAAS implements a Java version of the standard Pluggable Authentication Module (PAM) framework. See Making Login Services Independent from Authentication Technologies for further information.

Traditionally Java has provided codesource-based access controls (access controls based on where the code originated from and who signed the code). It lacked, however, the ability to additionally enforce access controls based on who runs the code. JAAS provides a framework that augments the Java security architecture with such support.

JAAS authentication is performed in a _pluggable_fashion. This permits applications to remain independent from underlying authentication technologies. New or updated authentication technologies can be plugged under an application without requiring modifications to the application itself. Applications enable the authentication process by instantiating aLoginContext object, which in turn references aConfiguration to determine the authentication technology(ies), or LoginModule(s), to be used in performing the authentication. TypicalLoginModules may prompt for and verify a user name and password. Others may read and verify a voice or fingerprint sample.

Once the user or service executing the code has been authenticated, the JAAS authorization component works in conjunction with the core Java SE access control model to protect access to sensitive resources. Unlike in the J2SDK 1.3 and earlier, where access control decisions are based solely on code location and code signers (a CodeSource), in the J2SDK 1.4 access control decisions are based both on the executing code's CodeSource and on the user or service running the code, who is represented by a Subjectobject. The Subject is updated by aLoginModule with relevant Principalsand credentials if authentication succeeds.

Who Should Read This Document

This document is intended for experienced developers who require the ability to design applications constrained by aCodeSource-based and Subject-based security model. It is also intended to be read by LoginModule developers (developers implementing an authentication technology) prior to reading the JAAS LoginModule Developer's Guide.

You may wish to first read the JAAS Authentication andJAAS Authorizationtutorials to get an overview of how to use JAAS and to see sample code in action, and then return to this document for further information.

This document assumes you have already read the following:

A supplement to this guide is the JAAS LoginModule Developer's Guide, intended for experienced programmers who require the ability to write a LoginModuleimplementing an authentication technology.

If you wish to learn more about the standard Pluggable Authentication Module (PAM) framework (JAAS implements a Java version of PAM), see Making Login Services Independent from Authentication Technologies.

The following tutorials for JAAS authentication and authorization can be run by everyone:

Similar tutorials for JAAS authentication and authorization, but which demonstrate the use of a Kerberos LoginModule and thus which require a Kerberos installation, can be found at

These two tutorials are a part of the Java GSS-API and JAAS sequence of tutorials that utilize Kerberos as the underlying technology for authentication and secure communication.


Core Classes and Interfaces

The JAAS-related core classes and interfaces can be broken into three categories: Common, Authentication, and Authorization.

Common Classes

Common classes are those shared by both the JAAS authentication and authorization components.

The key JAAS class is javax.security.auth.Subject, which represents a grouping of related information for a single entity such as a person. It encompasses the entity's Principals, public credentials, and private credentials.

Note that the java.security.Principal interface is used to represent a Principal. Also note that a credential, as defined by JAAS, may be any Object.

Subject

To authorize access to resources, applications first need to authenticate the source of the request. The JAAS framework defines the term subject to represent the source of a request. A subject may be any entity, such as a person or a service. Once the subject is authenticated, a javax.security.auth.Subjectis populated with associated identities, or Principals. A Subjectmay have many Principals. For example, a person may have a name Principal ("John Doe") and a SSNPrincipal ("123-45-6789"), which distinguish it from other subjects.

A Subject may also own security-related attributes, which are referred to as credentials. Sensitive credentials that require special protection, such as private cryptographic keys, are stored within a private credential Set. Credentials intended to be shared, such as public key certificates, are stored within a public credential Set. Different permissions (described below) are required to access and modify the different credentialSets.

Subjects are created using these constructors:

public Subject();

public Subject(boolean readOnly, Set principals,
               Set pubCredentials, Set privCredentials);

The first constructor creates a Subject with empty (non-null) Sets of Principals and credentials. The second constructor creates aSubject with the specified Sets ofPrincipals and credentials. It also has a boolean argument which can be used to make the Subjectread-only. In a read-only Subject, thePrincipal and credential Sets are immutable.

An application writer does not have to instantiate aSubject. If the application instantiates aLoginContext and does not pass aSubject to the LoginContextconstructor, the LoginContext instantiates a new empty Subject. See the LoginContext section.

If a Subject was not instantiated to be in a read-only state, it can be set read-only by calling the following method:

public void setReadOnly();

A javax.security.auth.AuthPermission with target "setReadOnly" is required to invoke this method. Once in a read-only state, any attempt to add or removePrincipals or credentials will result in anIllegalStateException being thrown.

The following method may be called to test aSubject's read-only state:

public boolean isReadOnly();

To retrieve the Principals associated with a Subject, two methods are available:

public Set getPrincipals();
public Set getPrincipals(Class c);

The first method returns all Principals contained in the Subject, while the second method only returns those Principals that are an instance of the specified Class c, or an instance of a subclass of Class c. An empty set will be returned if theSubject does not have any associatedPrincipals.

To retrieve the public credentials associated with aSubject, these methods are available:

public Set getPublicCredentials();
public Set getPublicCredentials(Class c);

The behavior of these methods is similar to that for thegetPrincipals methods, except in this case the public credentials are being obtained.

To access private credentials associated with aSubject, the following methods are available:

public Set getPrivateCredentials();
public Set getPrivateCredentials(Class c);

The behavior of these methods is similar to that for thegetPrincipals and getPublicCredentialsmethods.

To modify or operate upon a Subject'sPrincipal Set, public credentialSet, or private credential Set, callers use the methods defined in the java.util.Setclass. The following example demonstrates this:

Subject subject;
Principal principal;
Object credential;

. . .

// add a Principal and credential to the Subject
subject.getPrincipals().add(principal);
subject.getPublicCredentials().add(credential);

Note: An AuthPermission with target "modifyPrincipals", "modifyPublicCredentials", or "modifyPrivateCredentials" is required to modify the respectiveSets. Also note that only the sets returned via thegetPrincipals(),getPublicCredentials(), andgetPrivateCredentials() methods with no arguments are backed by the Subject's respective internal sets. Therefore any modification to the returned set affects the internal sets as well. The sets returned via thegetPrincipals(Class c),getPublicCredentials(Class c), andgetPrivateCredentials(Class c) methods are not backed by the Subject's respective internal sets. A new set is created and returned for each such method invocation. Modifications to these sets will not affect theSubject's internal sets.

In order to iterate through a Set of private credentials, you need ajavax.security.auth.PrivateCredentialPermission to access each credential. See the PrivateCredentialPermission API documentation for further information.

A Subject may be associated with anAccessControlContext (see the doAs anddoAsPrivileged method descriptions below). The following method returns the Subject associated with the specified AccessControlContext, ornull if no Subject is associated with the specified AccessControlContext.

public static Subject getSubject(final AccessControlContext acc);

An AuthPermission with target "getSubject" is required to call Subject.getSubject.

The Subject class also includes the following methods inherited from java.lang.Object.

public boolean equals(Object o);
public String toString();
public int hashCode();

The doAs methods for performing an action as a particular Subject

The following static methods may be called to perform an action as a particular Subject:

public static Object
    doAs(final Subject subject,
         final java.security.PrivilegedAction action);

public static Object
    doAs(final Subject subject,
         final java.security.PrivilegedExceptionAction action)
         throws java.security.PrivilegedActionException;

Both methods first associate the specifiedsubject with the current Thread'sAccessControlContext, and then execute theaction. This achieves the effect of having theaction run as the subject. The first method can throw runtime exceptions but normal execution has it returning an Object from the run method of itsaction argument. The second method behaves similarly except that it can throw a checked exception from itsPrivilegedExceptionAction run method. AnAuthPermission with target "doAs" is required to call the doAs methods.

Subject.doAs Example

Here is an example utilizing the first doAsmethod. Assume that someone named "Bob" has been authenticated by a LoginContext (see the LoginContext section) and as a result aSubject was populated with a Principalof class com.ibm.security.Principal, and thatPrincipal has the name "BOB". Also assume that a SecurityManager has been installed, and that the following exists in the access control policy (see the Policy section for more details on the policy file).

// grant "BOB" permission to read the file "foo.txt"
grant Principal com.ibm.security.Principal "BOB" {
    permission java.io.FilePermission "foo.txt", "read";
};

Here is the sample application code:

class ExampleAction implements java.security.PrivilegedAction {
    public Object run() {
        java.io.File f = new java.io.File("foo.txt");

        // the following call invokes a security check
        if (f.exists()) {
            System.out.println("File foo.txt exists");
        }
        return null;
    }
}

public class Example1 {
    public static void main(String[] args) {

        // Authenticate the subject, "BOB".
        // This process is described in the
        // [LoginContext](#LoginContext) section.

        Subject bob;
        // Set bob to the Subject created during the
        // authentication process

        // perform "ExampleAction" as "BOB"
        Subject.doAs(bob, new ExampleAction());
    }
}

During execution, ExampleAction will encounter a security check when it makes a call to f.exists(). However, since ExampleAction is running as "BOB", and the policy (above) grants the necessaryFilePermission to "BOB", theExampleAction will pass the security check. If thegrant statement in the policy is altered (adding an incorrect CodeBase or changing thePrincipal to "MOE", for example), then aSecurityException will be thrown.

The doAsPrivileged methods

The following methods also perform an action as a particularSubject.

public static Object doAsPrivileged(
    final Subject subject,
    final java.security.PrivilegedAction action,
    final java.security.AccessControlContext acc);

public static Object doAsPrivileged(
    final Subject subject,
    final java.security.PrivilegedExceptionAction action,
    final java.security.AccessControlContext acc)
    throws java.security.PrivilegedActionException;

An AuthPermission with target "doAsPrivileged" is required to call the doAsPrivileged methods.

doAs versus doAsPrivileged

The doAsPrivileged methods behave exactly the same as the doAs methods, except that instead of associating the provided Subject with the current Thread's AccessControlContext, they use the providedAccessControlContext. In this way, actions can be restricted by AccessControlContexts different from the current one.

An AccessControlContext contains information about all the code executed since theAccessControlContext was instantiated, including the code location and the permissions the code is granted by the policy. In order for an access control check to succeed, the policy must grant each code item referenced by theAccessControlContext the required permissions.

If the AccessControlContext provided todoAsPrivileged is null, then the action is not restricted by a separateAccessControlContext. One example where this may be useful is in a server environment. A server may authenticate multiple incoming requests and perform a separatedoAs operation for each request. To start eachdoAs action "fresh," and without the restrictions of the current server AccessControlContext, the server can call doAsPrivileged and pass in anull AccessControlContext.

Principals

As mentioned previously, Principals may be associated with a Subject if authentication is successful. Principals representSubject identities, and must implement the java.security.Principaland java.io.Serializableinterfaces. The Subject section describes ways to update the Principals associated with aSubject.

Credentials

Public and private credential classes are not part of the core JAAS class library. Any class can represent a credential. Developers, however, may elect to have their credential classes implement two interfaces related to credentials:Refreshable and Destroyable.

Refreshable

The javax.security.auth.Refreshable interface provides the capability for a credential to refresh itself. For example, a credential with a particular time-restricted lifespan may implement this interface to allow callers to refresh the time period for which it is valid. The interface has two abstract methods:

boolean isCurrent();

This method determines whether the credential is current or valid.

void refresh() throws RefreshFailedException;

This method updates or extends the validity of the credential. The method implementation should perform anAuthPermission("refreshCredential") security check to ensure the caller has permission to refresh the credential.

Destroyable

The javax.security.auth.Destroyable interface provides the capability of destroying the contents within a credential. The interface has two abstract methods:

boolean isDestroyed();

Determines whether the credential has been destroyed.

void destroy() throws DestroyFailedException;

Destroys and clears the information associated with this credential. Subsequent calls to certain methods on this credential will result in an IllegalStateExceptionbeing thrown. The method implementation should perform anAuthPermission("destroyCredential") security check to ensure the caller has permission to destroy the credential.

Authentication Classes and Interfaces

To authenticate a subject (user or service), the following steps are performed:

  1. An application instantiates a LoginContext.
  2. The LoginContext consults a Configuration to load all of theLoginModules configured for that application.
  3. The application invokes the LoginContext'slogin method.
  4. The login method invokes all of the loadedLoginModules. Each LoginModule attempts to authenticate the subject. Upon success,LoginModules associate relevantPrincipals and credentials with aSubject object that represents the subject being authenticated.
  5. The LoginContext returns the authentication status to the application.
  6. If authentication succeeded, the application retrieves theSubject from the LoginContext.

The authentication classes are described below.

LoginContext

The javax.security.auth.login.LoginContext class provides the basic methods used to authenticate subjects, and provides a way to develop an application independent of the underlying authentication technology. The LoginContext consults a Configuration to determine the authentication services, or LoginModule(s), configured for a particular application. Therefore, differentLoginModules can be plugged in under an application without requiring any modifications to the application itself.

LoginContext offers four constructors from which to choose:

public LoginContext(String name) throws LoginException;

public LoginContext(String name, Subject subject) throws LoginException;

public LoginContext(String name, CallbackHandler callbackHandler)
       throws LoginException

public LoginContext(String name, Subject subject,
       CallbackHandler callbackHandler) throws LoginException

All of the constructors share a common parameter:name. This argument is used by theLoginContext as an index into the login Configuration to determine which LoginModules are configured for the application instantiating theLoginContext. Constructors that do not take aSubject as an input parameter instantiate a newSubject. Null inputs are disallowed for all constructors. Callers require an AuthPermission with target "createLoginContext." to instantiate aLoginContext. Here, refers to the name of the login configuration entry that the application references in the name parameter for theLoginContext instantiation.

See the CallbackHandler section for information on what a CallbackHandler is and when you may need one.

Actual authentication occurs with a call to the following method:

public void login() throws LoginException;

When login is invoked, all of the configuredLoginModules are invoked to perform the authentication. If the authentication succeeded, theSubject (which may now hold Principals, public credentials, and private credentials) can be retrieved by using the following method:

 public Subject getSubject();

To logout a Subject and remove its authenticatedPrincipals and credentials, the following method is provided:

public void logout() throws LoginException;

The following code sample demonstrates the calls necessary to authenticate and logout a Subject:

// let the LoginContext instantiate a new Subject
LoginContext lc = new LoginContext("entryFoo");
try {
    // authenticate the Subject
    lc.login();
    System.out.println("authentication successful");

    // get the authenticated Subject
    Subject subject = lc.getSubject();

    ...

    // all finished -- logout
    lc.logout();
} catch (LoginException le) {
    System.err.println("authentication unsuccessful: " +
        le.getMessage());
}

LoginModule

The LoginModule interface gives developers the ability to implement different kinds of authentication technologies that can be plugged in under an application. For example, one type ofLoginModule may perform a user name/password-based form of authentication. Other LoginModules may interface to hardware devices such as smart cards or biometric devices.

Note: If you are an application writer, you do not need to understand the workings of LoginModules. All you have to know is how to write your application and specify configuration information (such as in a login configuration file) such that the application will be able to utilize the LoginModule specified by the configuration to authenticate the user.

If, on the other hand, you are a programmer who wishes to write a LoginModule implementing an authentication technology, see the JAASLoginModule Developer's Guide for detailed step-by-step instructions.

CallbackHandler

In some cases a LoginModule must communicate with the user to obtain authentication information.LoginModules use a javax.security.auth.callback.CallbackHandler for this purpose. Applications implement the CallbackHandler interface and pass it to the LoginContext, which forwards it directly to the underlyingLoginModules. A LoginModule uses theCallbackHandler both to gather input from users (such as a password or smart card pin number) or to supply information to users (such as status information). By allowing the application to specify the CallbackHandler, underlying LoginModules can remain independent of the different ways applications interact with users. For example, the implementation of a CallbackHandler for a GUI application might display a window to solicit input from a user. On the other hand, the implementation of aCallbackHandler for a non-GUI tool might simply prompt the user for input directly from the command line.

CallbackHandler is an interface with one method to implement:

 void handle(Callback[] callbacks)
     throws java.io.IOException, UnsupportedCallbackException;

The LoginModule passes the CallbackHandler handle method an array of appropriateCallbacks, for example a NameCallbackfor the user name and a PasswordCallback for the password, and theCallbackHandler performs the requested user interaction and sets appropriate values in theCallbacks. For example, to process aNameCallback, the CallbackHandler may prompt for a name, retrieve the value from the user, and call theNameCallback's setName method to store the name.

The CallbackHandler documentation has a lengthy example not included in this document that readers may want to examine.

Callback

The javax.security.auth.callback package contains theCallback interface as well as several implementations. LoginModules may pass an array ofCallbacks directly to the handle method of a CallbackHandler.

Please consult the various Callback APIs for more information on their use.

To make JAAS authorization take place, granting access control permissions based not just on what code is running but also on who is running it, the following is required:

The Policy abstract class and the authorization-specific classes AuthPermission andPrivateCredentialPermission are described below.

Policy

The java.security.Policyclass is an abstract class for representing the system-wide access control policy. The Policy API was upgraded in the J2SDK 1.4 to support Principal-based queries.

As a default, the J2SDK provides a file-based subclass implementation, which was upgraded to supportPrincipal-based grant entries in policy files.

Policy files and the structure of entries within them are described in Default Policy Implementation and Policy File Syntax.

AuthPermission

The javax.security.auth.AuthPermissionclass encapsulates the basic permissions required for JAAS. AnAuthPermission contains a name (also referred to as a "target name") but no actions list; you either have the named permission or you don't.

In addition to its inherited methods (from the java.security.Permissionclass), an AuthPermission has two public constructors:

public AuthPermission(String name);
public AuthPermission(String name, String actions);

The first constructor creates a new AuthPermissionwith the specified name. The second constructor also creates a new AuthPermission object with the specified name, but has an additional actions argument which is currently unused and should be null. This constructor exists solely for the Policy object to instantiate newPermission objects. For most other code, the first constructor is appropriate.

Currently the AuthPermission object is used to guard access to the Policy, Subject,LoginContext, and Configurationobjects. Please refer to the AuthPermissionjavadocs for the list of valid names that are supported.

PrivateCredentialPermission

Thejavax.security.auth.PrivateCredentialPermissionclass protects access to a Subject's private credentials and provides one public constructor:

 public PrivateCredentialPermission(String name, String actions);

Please refer to the PrivateCredentialPermission javadocs for more detailed information on this class.


JAAS Tutorials and Sample Programs

The JAAS Authentication and JAAS Authorizationtutorials contain the following samples:

See the tutorials for detailed information about the applications, the policy files, and the login configuration file.

Application writers do not need to understand the code for SampleLoginModule.java or SamplePrincipal.java, as explained in the tutorials. Programmers who wish to write LoginModules can learn how to do so by reading the JAAS LoginModule Developer's Guide.


Appendix A: JAAS Settings in the java.security Security Properties File

A number of JAAS-related settings can be configured in thejava.security master security properties file, which is located in the lib/security directory of the Java runtime.

JAAS adds two new security properties tojava.security:

The following pre-existing properties are also relevant for JAAS users:

The following example demonstrates how to configure these properties. In this example, we leave the values provided in the default java.security file for the policy.provider, policy.url.n, and login.configuration.provider properties. The default java.security file also lists a value for the login.config.url.n property, but it is commented out. In the example below, it is not commented.

...

Class to instantiate as the javax.security.auth.login.Configuration

provider.

login.configuration.provider=com.sun.security.auth.login.ConfigFile

Default login configuration file

login.config.url.1=file:${user.home}/.java.login.config

Class to instantiate as the system Policy. This is the name of the class

that will be used as the Policy object.

policy.provider=sun.security.provider.PolicyFile

The default is to have a single system-wide policy file,

and a policy file in the user's home directory.

policy.url.1=file:${java.home}/lib/security/java.policy policy.url.2=file:${user.home}/.java.policy

...

Note: Modifications made to this file may be overwritten by subsequent JRE updates. However, an alternate java.security properties file may be specified from the command line via the system property java.security.properties=<URL>. This properties file appends to the system properties file. If both properties files specify values for the same key, the value from command-line properties file is selected, as it is the last one loaded.

Also, specifying java.security.properties==<URL> (using two equals signs), then that properties file will completely override the system properties file.

To disable the ability to specify an additional properties file from the command line, set the key security.overridePropertiesFileto false in the system properties file. It is set to true by default.

Login Configuration Provider

The default JAAS login configuration implementation provided by Oracle gets its configuration information from files and expects the information to be provided in a specific format shown in the tutorials.

The default JAAS login configuration implementation can be replaced by specifying the alternative provider class implementation in the login.configuration.providerproperty.

For example:

login.configuration.provider=com.foo.Config

If the Security propertylogin.configuration.provider is not found, or is left unspecified, then it is set to the default value:

login.configuration.provider=com.sun.security.auth.login.ConfigFile

Note that there is no means to dynamically set the login configuration provider from the command line.

Login Configuration URLs

If you are using a login configuration implementation that expects the configuration information to be specified in files (as does the default implementation from Oracle), the location of the login configuration file(s) can be statically set by specifying their respective URLs in thelogin.config.url._n_ property. 'n' is a consecutively numbered integer starting with 1. If multiple configuration files are specified (if n >= 2), they will be read and unioned into one single configuration.

For example:

login.config.url.1=file:C:/config/.java.login.config login.config.url.2=file:C:/users/foo/.foo.login.config

If the location of the configuration files is not set in thejava.security properties file, and also is not specified dynamically from the command line (via the-Djava.security.auth.login.config option), JAAS attempts to load a default configuration from

file:${user.home}/.java.login.config

Policy Provider

The default policy implementation can be replaced by specifying the alternative provider class implementation in thepolicy.provider property.

For example:

policy.provider=com.foo.Policy

If the Security property policy.provider is not found, or is left unspecified, then the Policy is set to the default value:

policy.provider=sun.security.provider.PolicyFile

Note that there is no means to dynamically set the policy provider from the command line.

Policy File URLs

The location of the access control policy files can be statically set by specifying their respective URLs in theauth.policy.url._n_ property. 'n' is a consecutively numbered integer starting with 1. If multiple policies are specified (if n >= 2), they will be read and unioned into one single policy.

For example:

policy.url.1=file:C:/policy/.java.policy policy.url.2=file:C:/users/foo/.foo.policy

If the location of the policy file(s) is not set in thejava.security properties file, and is not specified dynamically from the command line (via the-Djava.security.policy option), the access control policy defaults to the same policy as that of the system policy file installed with the J2SDK. That policy file


Appendix B: Example Login Configurations

Login configurations are located using thelogin.config.url.n security properties found in thejava.security file. For more information about this property and the location of the java.security file, see Appendix A.

The default Configuration implementation,ConfigFile, gets its configuration information from login configuration files. For details about the default login Configuration implementation provided with JAAS, please consult the javadocs for the com.sun.security.auth.login.ConfigFileclass.

The following is a sample login configuration file.

Login1 {
   sample.SampleLoginModule required debug=true;
};

Login2 {
   sample.SampleLoginModule required;
   com.sun.security.auth.module.NTLoginModule sufficient;
   com.foo.SmartCard requisite debug=true;
   com.foo.Kerberos optional debug=true;
};

The application Login1 only has one configured LoginModule, SampleLoginModule. Therefore, an attempt by Login1 to authenticate a subject (user or service) will be successful if and only if theSampleLoginModule succeeds.

The authentication logic for the application Login2 is easier to explain with the table below. Note: therequired, sufficient,requisite, and optional flags are described in the Configuration javadocs.

Login2 Authentication Status

Module Class Flag Authentication Attempt 1 Authentication Attempt 2 Authentication Attempt 3 Authentication Attempt 4 Authentication Attempt 5 Authentication Attempt 6 Authentication Attempt 7 Authentication Attempt 8
SampleLoginModule required pass pass pass pass fail fail fail fail
NTLoginModule sufficient pass fail fail fail pass fail fail fail
SmartCard requisite * pass pass fail * pass pass fail
Kerberos optional * pass fail * * pass fail *
Overall Authentication not applicable pass pass pass fail fail fail fail fail

* = trivial value due to control returning to the application because a previous requisite module failed or a previous_sufficient_ module succeeded.