Skip to main content


developerWorks  >   Java™ technology  >   IBM developer kits  >   Security information  >   5.0  >  

Security information

The following pages contain documentation, example code, and ancillary files relating to IBM's SDKs. The documentation covers IBM-specific features of IBM's offerings. A platform-specific Security User Guide is included in each download. For information about the SDK for z/OS product and security components specific to that platform, see this Web site.

Before you can download code, you will need an IBM Registration ID. You can read about IBM Registration here.

developerWorks

JAAS Reference Guide

JavaTM Authentication and Authorization Service (JAAS) 2.0

Reference Guide

for the JavaTM 2 SDK, Standard Edition, v 5.0



Introduction
Who Should Read This Document
Related Documentation

What's New in JAAS in the J2SDK, v 1.4.2

Core Classes and Interfaces
Common Classes
Subject
Principals
Credentials
Authentication Classes and Interfaces
LoginContext
LoginModule
CallbackHandler
Callback
Authorization Classes
Policy
AuthPermission
PrivateCredentialPermission

Implementation

"Hello World", JAAS style!

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

Appendix B: Example Login Configurations

Appendix C: Authorization Policy File

Appendix D: ThreadSubject (NT, Windows 2000, Windows 2000 64 Bit, and OS/390)

Appendix E: SAFPermission for OS/390 JAAS

Appendix F: OS/390 LoginModule


Introduction

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

JAAS can be used for two purposes:

  • for authentication of users, to reliably and securely determine who is currently executing Java code, regardless of whether the code is running as an application, an applet, a bean, or a servlet; and

  • for authorization of users to ensure they have the access control rights (permissions) required to do the actions performed.

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 2 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 2 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 a LoginContext object, which in turn references a Configuration to determine the authentication technology(ies), or LoginModule(s), to be used in performing the authentication. Typical LoginModules may prompt for and verify a username 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 2 access control model to protect access to sensitive resources. Unlike in the J2SDK, v 1.3 and earlier, where access control decisions are based solely on code location and code signers (a CodeSource), in the J2SDK, v 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 Subject object. The Subject is updated by a LoginModule with relevant Principals and 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 a CodeSource-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.

Related Documentation

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

What's New in JAAS in the J2SDK, v 1.4

Below are listed the differences between the previous version of JAAS (JAAS 1.0) and the JAAS within the J2SDK, v 1.4.

JAAS Is Now in J2SDK

JAAS was previously an optional package (extension) to the JavaTM 2 SDK, Standard Edition (J2SDK), versions 1.2.x. JAAS has now been integrated into the J2SDK, v 1.4. JAAS augments the core Java 2 platform with the means to authenticate and enforce access controls upon users.

The major ramification of this integration stems around the system security policy. The J2SDK, versions 1.2 and earlier, has its own security policy class (java.security.Policy). JAAS 1.0, as an optional package, provided an additional Principal-based security policy (javax.security.auth.Policy). Upon integration into the core SDK, the JAAS policy has been deprecated in favor of the SDK policy.

The SDK Policy API was upgraded to support Principal-based queries, and the Policy reference implementation was upgraded to support Principal-based grant entries in policy files, where such an entry may include a Principal field indicating that the user or other entity represented by the specified Principal, executing the specified code, has the designated permissions. In addition, the graphical Policy Tool utility used to create policy files was enhanced to support inclusion of Principal fields. Appropriately, the JAAS 1.0 Policy reference implementation and its supporting classes in the com.ibm.security.auth package have been deprecated.

Please reference the Policy Document for more information on the Policy reference implementation and a list of the relevant API changes.

New Classes/Interfaces

Additions include

Deprecated Items

Deprecated items include:


Core Classes and Interfaces

The JAAS-related core classes and interfaces can be broken into 3 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.Subject is populated with associated identities, or Principals. A Subject may have many Principals. For example, a person may have a name Principal ("John Doe") and a SSN Principal ("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 credential Sets.

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 a Subject with the specified Sets of Principals and credentials. It also has a boolean argument which can be used to make the Subject read-only. In a read-only Subject, the Principal and credential Sets are immutable.

An application writer does not have to instantiate a Subject. If the application instantiates a LoginContext and does not pass a Subject to the LoginContext constructor, 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 remove Principals or credentials will result in an IllegalStateException being thrown.

The following method may be called to test a Subject'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 the Subject does not have any associated Principals.

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

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

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

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

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

The behavior of these methods is similar to that for the getPrincipals and getPublicCredentials methods.

To modify or operate upon a Subject's Principal Set, public credential Set, or private credential Set, callers use the methods defined in the java.util.Set class. 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 respective Sets. Also note that only the sets returned via the getPrincipals(), getPublicCredentials(), and getPrivateCredentials() 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 the getPrincipals(Class c), getPublicCredentials(Class c), and getPrivateCredentials(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 the Subject's internal sets.

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

A Subject may be associated with an AccessControlContext (see the doAs and doAsPrivileged method descriptions below). The following method returns the Subject associated with the specified AccessControlContext, or null 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 specified subject with the current Thread's AccessControlContext, and then execute the action. This achieves the effect of having the action run as the subject. The first method can throw runtime exceptions but normal execution has it returning an Object from the run method of its action argument. The second method behaves similarly except that it can throw a checked exception from its PrivilegedExceptionAction run method. An AuthPermission with target "doAs" is required to call the doAs methods.

Subject.doAs Example 1

Here is an example utilizing the first doAs method. Assume that someone named "Bob" has been authenticated by a LoginContext (see the LoginContext section) and as a result a Subject was populated with a Principal of class com.ibm.security.Principal, and that Principal 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 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 necessary FilePermission to "BOB", the ExampleAction will pass the security check.

Example 2 has the same scenario as Example 1.

Subject.doAs Example 2

    public class Example2 {
        // Example of using an anonymous action class.
        public static void main(String[] args) {
            // Authenticate the subject, "BOB".
            // This process is described in the
            // LoginContext section.

            Subject bob;
            ...

            // perform "ExampleAction" as "BOB":
                Subject.doAs(bob, new ExampleAction() {
                public Object run() {
                    java.io.File f = new java.io.File("foo.txt");
                    if (f.exists()) {
                        System.out.println("File foo.txt exists.");
                    }
                    return null;
                }
            });
        }
    }

 

Both examples throw a SecurityException if the grant statement in the policy is altered (adding an incorrect CodeBase or changing the Principal to "MOE", for example), then a SecurityException will be thrown.

Since both examples perform the same function, there must be a reason to write code one way over the other. Example 1 may be easier to read for some programmers unfamiliar with anonymous classes. Also, the action class could be placed in a separate file with a unique CodeBase and then the permission grant could utilize this information. Example 2 is more compact and the action to be performed is easier to find since it is right there in the doAs call.

The doAsPrivileged methods

The following methods also perform an action as a particular Subject.

    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 vs. 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 provided AccessControlContext. In this way, actions can be restricted by AccessControlContexts different from the current one.

An AccessControlContext contains information about all the code executed since the AccessControlContext 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 the AccessControlContext the required permissions.

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

Principals

As mentioned previously, Principals may be associated with a Subject if authentication is successful. Principals represent Subject identities, and must implement the java.security.Principal and java.io.Serializable interfaces. The Subject section describes ways to update the Principals associated with a Subject.

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 an AuthPermission("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 IllegalStateException being thrown. The method implementation should perform an AuthPermission("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 the LoginModules configured for that application.

  3. The application invokes the LoginContext's login method.

  4. The login method invokes all of the loaded LoginModules. Each LoginModule attempts to authenticate the subject. Upon success, LoginModules associate relevant Principals and credentials with a Subject object that represents the subject being authenticated.

  5. The LoginContext returns the authentication status to the application.

  6. If authentication succeeded, the application retrieves the Subject 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, different LoginModules 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 the LoginContext as an index into the login Configuration to determine which LoginModules are configured for the application instantiating the LoginContext. Constructors that do not take a Subject as an input parameter instantiate a new Subject. Null inputs are disallowed for all constructors. Callers require an AuthPermission with target "createLoginContext.<name>" to instantiate a LoginContext. Here, <name> refers to the name of the login configuration entry that the application references in the name parameter for the LoginContext 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 configured LoginModules are invoked to perform the authentication. If the authentication succeeded, the Subject (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 authenticated Principals and credentials, the following method is provided:

    public void logout() throws LoginException;
The following snippet of code in an application will authenticate a Subject called "bob" after accessing a configuration file with a configuration entry named "moduleFoo":

    Subject bob = new Subject();
    LoginContext lc = new LoginContext("moduleFoo", bob);
    try {
        lc.login();
        System.out.println("authentication successful");
    } catch (LoginException le) {
        System.out.println("authentication unsuccessful"+le.printStackTrace());
    }
This snippet of code in an application will authenticate a "nameless" Subject and then use the getSubject method to retrieve it:

    LoginContext lc = new LoginContext("moduleFoo");
    try {
        lc.login();
        System.out.println("authentication successful");
    } catch (LoginException le) {
        System.out.println("authentication unsuccessful"+le.printStackTrace());
    }
    Subject subject = lc.getSubject();

If the authentication failed, then getSubject returns null. Also, there isn't an AuthPermission("getSubject") required to do this as is the case for Subject.getSubject.

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 of LoginModule may perform a username/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 JAAS LoginModule 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 underlying LoginModules. A LoginModule uses the CallbackHandler 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 a CallbackHandler 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 appropriate Callbacks, for example a NameCallback for the user name and a PasswordCallback for the password, and the CallbackHandler performs the requested user interaction and sets appropriate values in the Callbacks. For example, to process a NameCallback, the CallbackHandler may prompt for a name, retrieve the value from the user, and call the NameCallback'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 the Callback interface as well as several implementations. LoginModules may pass an array of Callbacks directly to the handle method of a CallbackHandler.

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

Authorization Classes

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 user must be authenticated, as described in the LoginContext section.

  • The Subject that is the result of authentication must be associated with an access control context, as described in the Subject section.

  • Principal-based entries must be configured in the security policy, as described below.

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

Policy

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

As a default, the J2SDK provides a file-based subclass implementation, which was upgraded to support Principal-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.AuthPermission class encapsulates the basic permissions required for JAAS. An AuthPermission 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 class), an AuthPermission has two public constructors:

    public AuthPermission(String name);
    public AuthPermission(String name, String actions);
The first constructor creates a new AuthPermission with 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 new Permission 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 Configuration objects. Please refer to the AuthPermission javadocs for the list of valid names that are supported.

PrivateCredentialPermission

The javax.security.auth.PrivateCredentialPermission class 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.


Implementation

Note: Appendix A contains a sample java.security file that includes the static properties mentioned here.

Because there exists default values for JAAS providers and policy files, users need not statically (in the java.security file) nor dynamically (command line -D option) list their values in order to implement JAAS. Also, the default configuration and policy file providers may be replaced by a user-developed provider. Therefore this section is an attempt to explain the JAAS default providers and policy files as well as the properties that enable alternative providers.

If desirable, read the Default Policy File API and Default Configuration File API for more information than is summarized here.

Authentication Provider

The authentication provider, or configuration class, is statically set with login.configuration.provider=[class] in the java.security file. This provider creates the Configuration object.

For example:


    login.configuration.provider=com.foo.Config

If the Security property login.configuration.provider is not found in java.security, then JAAS will set it to the default value:
com.ibm.security.auth.login.ConfigFile.

If a security manager is set before the Configuration is created, then an AuthPermission("getLoginConfiguration") will be required to be granted.

There isn't a way to dynamically set the configuration provider on the command line.

Authentication Configuration File

The authentication configuration files may be statically set in java.security with login.config.url.n=[URL], where n is a consecutively number integer starting with 1. The format is identical to the format for Java security policy files (policy.url.n=[URL]).

If the Security property policy.allowSystemProperty is set to "true" in java.security, then users can dynamically set policy files on the command line utilizing the -D option with this property: java.security.auth.login.config. The value may be a path or URL. For example,

(Unix):

    ... -Djava.security.auth.login.config=/usr/config_policy/login.config ...
    or
    ... -Djava.security.auth.login.config=file:/usr/config_policy/login.config ...
(Windows):
    ... -Djava.security.auth.login.config=c:\config_policy\login.config ...
    or
    ... -Djava.security.auth.login.config=file:c:/config_policy/login.config ...
Note: using double equal signs (==) on the command line allows a user to override all other policy files found.

If no configuration files can be found statically or dynamically, JAAS will try to load the configuration file from this default location: ${user.home}/.java.login.config where ${user.home} is a system dependent location. 

Authorization Provider

The authorization provider, or JAAS Policy class, is statically set with auth.policy.provider=[class] in the java.security file. This provider creates the JAAS Subject-based Policy object.

For example:

    auth.policy.provider=com.foo.Policy
If the Security property auth.policy.provider is not found in java.security, then JAAS will set it to the default value:
com.ibm.security.auth.PolicyFile.

If a security manager is set before the Configuration is created, then an AuthPermission("getPolicy") will be required to be granted.

There isn't a way to dynamically set the authorization provider on the command line.

Authorization Policy File

The authorization policy files may be statically set in java.security with auth.policy.url.n=[URL], where n is a consecutively number integer starting with 1. The format is identical to the format for Java security policy files (policy.url.n=[URL]).

If the Security property policy.allowSystemProperty is set to "true" in java.security, then users can dynamically set policy files on the command line utilizing the -D option with this property: java.security.auth.policy. The value may be a path or URL. For example,

(Unix):

   ... -Djava.security.auth.policy=/usr/auth_policy/java.auth.policy ...
   or
   ... -Djava.security.auth.policy=file:/usr/auth_policy/java.auth.policy ...
(Windows)
   ... -Djava.security.auth.policy=c:\auth_policy\java.auth.policy ...
   or
   ... -Djava.security.auth.policy=file:c:/auth_policy/java.auth.policy ...
Note: using double equal signs (==) on the command line allows a user to override all other policy files found.

There is not a default location to load an authorization policy from.


"Hello World", JAAS style!

Put on your dark sunglasses and favorite fedora hat, then grab an alto sax ... it's time to get JAAS-y! Yes, another "Hello World!" program. In this section, a program will be made available to test your JAAS installation.

Retrieve Files

Download the HelloWorld.tar for your platform from the index page to your test directory. Expand it using "tar -xvf HelloWorld.tar" or "winzip" on Windows.

You should verify the contents of your test directory.

source files:
  • HWLoginModule.java
  • HWPrincipal.java
  • HelloWorld.java
class files
  • The source files have been precompiled for you into the classes directory.
policy files
  • jaas.config
  • java2.policy
  • jaas.policy
Compile Source Files

NOTE: the example uses Windows-style file separators ("\"). Unix users should substitute forward slashes ("/") in the example.

The three source files, HWLoginModule.java, HWPrincipal.java and HelloWorld.java, are already compiled and therefore do not need to be compiled.

If any of the source files are modified, then change to the test directory that they were saved to and enter:

javac -d .\classes *.java
The classpath should need the classes directory (.\classes) added to it in order to compile the classes.

Note: HWLoginModule and HWPrincipal are in the com.ibm.security package and will be created in the appropriate directory during compilation (\classes\com\ibm\security).

Examine Policy Files
The configuration file, jaas.config, contains one entry:

helloWorld {
   com.ibm.security.HWLoginModule required debug=true;
};
Only one LoginModule is supplied with the test case. When executing the HelloWorld application, please experiment by changing the LoginModuleControlFlag (required, requisite, sufficient, optional) and deleting the debug flag. If more LoginModules are available for testing, then feel free to alter this configuration and experiment with multiple LoginModules. HWLoginModule will be discussed shortly.

The Java 2 policy file, java2.policy, contains one permission block:

grant {
   permission javax.security.auth.AuthPermission "createLoginContext";
   permission javax.security.auth.AuthPermission "modifyPrincipals";
   permission javax.security.auth.AuthPermission "doAsPrivileged";
};
The three permissions are required because the HelloWorld application (1) creates a LoginContext object, (2) modifies the Principals of the the authenticated Subject and (3) calls the doAsPrivileged method of the Subject class.

The JAAS policy file, jaas.policy, also contains one permission block:

grant Principal com.ibm.security.HWPrincipal "bob" {
   permission java.util.PropertyPermission "java.home", "read";
   permission java.util.PropertyPermission "user.home", "read";
   permission java.io.FilePermission "foo.txt", "read";
};
The three permissions are initially granted to an HWPrincipal named bob. The actual Principal added to the authenticated Subject is the username used during the login process (more later). Here's the action code from HelloWorld with the three system calls (the reason for the required permissions) in bold
   Subject.doAsPrivileged(lc.getSubject(), new PrivilegedAction() {
       public Object run() {
           System.out.println("\nYour java.home property: "
                                   +System.getProperty("java.home"));

           System.out.println("\nYour user.home property: "
                                   +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 your current directory");

           System.out.println("\nOh, by the way ...");

           try {
               Thread.currentThread().sleep(2000);
           } catch (Exception e) {
               // ignore
           }
           System.out.println("\n\nHello World!\n");
           return null;
       }
   }, null);
When executing the HelloWorld program, use various usernames and alter jaas.policy accordingly. There should not be a need to alter java2.policy. Also, create a file called foo.txt in the test directory to test the last system call.

Examine Source Files
The LoginModule, HWLoginModule, simply authenticates any user who enters the correct password (case sensitive): Go JAAS.

 The HelloWorld application permits users three attempts to do so. When Go JAAS is correctly entered, an HWPrincipal with a name equal the the username is added to the authenticated Subject.

The Principal class, HWPrincipal, represents a Principal based on the username entered. It is this name that is important when granting permissions to authenticated Subjects.

The main application, HelloWorld, first creates a LoginContext based on a configuration entry with the name helloWorld. The configuration file has already been discussed. Callbacks are used to retrieve user input. Look at the MyCallbackHandler class located in the HelloWorld.java file to see this process.

   LoginContext lc = null;
   try {
       lc = new LoginContext("helloWorld", new MyCallbackHandler());
   } catch (LoginException le) {
       le.printStackTrace();
       System.exit(-1);
   }
The user enters a username/password (up to three times) and if Go JAAS is entered as the password, then the Subject is authenticated (HWLoginModule adds a HWPrincipal to the Subject).

As mentioned previously, work is then performed as the authenticated Subject.

Run HelloWorld Test

To run the HelloWorld program, first change to the test directory. The configuration and policy files will need to be loaded. See Implementation for the correct properties to set either in java.security or on the command line. The latter method will be discussed here.

The following command has been broken up into several lines for clarity. Enter as one continuous command.

java -Djava.security.manager=
     -Djava.security.auth.login.config=.\jaas.config
     -Djava.security.policy=.\java2.policy
     -Djava.security.auth.policy=.\jaas.policy
     HelloWorld
Note: the use of ".\filename" for the policy files is necessary because each user's test directory canonical path will vary. If desired, substitute "." with the path to the test directory. For example, if the test directory is "c:\test\hello", then the first file would be changed to:
   -Djava.security.auth.login.config=c:\test\hello\jaas.config
If the policy files are not found, a SecurityException will be thrown. Otherwise, information concerning your java.home and user.home properties will be displayed. Also, the existence of a file called foo.txt in your test directory will be checked. Finally, the ubiquitous "Hello World" message is displayed.

Having Fun With HelloWorld

Rerun HelloWorld as many times as you like. It has already been suggested to vary the username/passwords entered, change the configuration file entries, change the policy file permissions, and to even add (stack) additional LoginModules to the helloWorld configuration entry. You could add codebase fields to the policy files too.

Finally, try running the program without a SecurityManager to see how it works if you run into problems.


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

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

JAAS adds two new security properties to java.security:

  • login.configuration.provider
  • login.config.url.n

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

  • policy.provider
  • policy.url.n

Login Configuration Provider

The default JAAS login configuration implementation provided by IBM 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.provider property.

For example:

  login.configuration.provider=com.foo.Config
If the Security property login.configuration.provider is not found, or is left unspecified, then it is set to the default value:
  login.configuration.provider=com.ibm.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 IBM), the location of the login configuration file(s) can be statically set by specifying their respective URLs in the login.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 the java.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 the policy.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 the auth.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 the java.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 the J2SDK. That policy file

  • grants all permissions to standard extensions

  • allows anyone to listen on un-privileged ports

  • allows any code to read certain "standard" properties that are not security-sensitive, such as the "os.name" and "file.separator" properties.

Sample Master Security Properties File

Below is a modified copy of the java.security file provided with the Java 2 runtime, v 1.4. Example settings for JAAS-related properties are shown in bold. 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.

#
# This is the "master security properties file".
#
# In this file, various security properties are set for use by
# java.security classes. This is where users can statically register
# Cryptography Package Providers ("providers" for short). The term
# "provider" refers to a package or set of packages that supply a
# concrete implementation of a subset of the cryptography aspects of
# the Java Security API. A provider may, for example, implement one or
# more digital signature algorithms or message digest algorithms.
#
# Each provider must implement a subclass of the Provider class.
# To register a provider in this master security properties file,
# specify the Provider subclass name and priority in the format
#
#    security.provider.<n>=<className>
#
# This declares a provider, and specifies its preference
# order <n>. The preference order is the order in which providers are
# searched for requested algorithms (when no specific provider is
# requested). The order is 1-based; 1 is the most preferred, followed
# by 2, and so on.
#
# <className> must specify the subclass of the Provider class whose
# constructor sets the values of various properties that are required
# for the Java Security API to look up the algorithms or other
# facilities implemented by the provider.
#
# There must be at least one provider specification in java.security.
# The number 1 is used for the default provider.
#
# Note: Statically registered Provider subclasses are instantiated
# when the system is initialized. Providers can be dynamically
# registered instead by calls to either the addProvider or
# insertProviderAt method in the Security class.

#
# List of providers and their preference orders (see above):
#
security.provider.1=com.ibm.jsse.IBMJSSEProvider
security.provider.2=com.ibm.crypto.provider.IBMJCE
security.provider.3=com.ibm.security.jgss.IBMJGSSProvider
security.provider.4=com.ibm.security.cert.IBMCertPath

#
# Select the source of seed data for SecureRandom. By default it uses
# a system/thread activity algorithm. Optionally, if the platform supports
# it an entropy gathering device can be selected.
#
#securerandom.source=file:/dev/random
#
# The entropy gathering device is described as a URL and can
# also be specified with the property "java.security.egd". For example,
#   -Djava.security.egd=file:/dev/urandom
# Specifying this property will override the securerandom.source setting.

#
# Class to instantiate as the javax.security.auth.login.Configuration
# provider.
#
login.configuration.provider=com.ibm.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

# whether or not we expand properties in the policy file
# if this is set to false, properties (${...}) will not be expanded in policy
# files.
policy.expandProperties=true

# whether or not we allow an extra policy to be passed on the command line
# with -Djava.security.policy=somefile. Comment out this line to disable
# this feature.
policy.allowSystemProperty=true

# whether or not we look into the IdentityScope for trusted Identities
# when encountering a 1.1 signed JAR file. If the identity is found
# and is trusted, we grant it AllPermission.
policy.ignoreIdentityScope=false

#
# Default keystore type.
#
keystore.type=jks

#
# Class to instantiate as the system scope:
#
system.scope=sun.security.provider.IdentityDatabase

#
# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.

#
# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
# passed to checkPackageDefinition unless the
# corresponding RuntimePermission ("defineClassInPackage."+package) has
# been granted.
#
# by default, no packages are restricted for definition, and none of
# the class loaders supplied with the JDK call checkPackageDefinition.
#
#package.definition=

#
# Determines whether this properties file can be appended to
# or overridden on the command line via -Djava.security.properties
#
security.overridePropertiesFile=true

#
# Determines the default key and trust manager factory algorithms for
# the javax.net.ssl package.
#
ssl.KeyManagerFactory.algorithm=IbmX509
ssl.TrustManagerFactory.algorithm=IbmX509

#
# Determines the default SSLSocketFactory and SSLServerSocketFactory
# provider implementations for the javax.net.ssl package.  If, due to
# export and/or import regulations, the providers are not allowed to be
# replaced, changing these values will produce non-functional
# SocketFactory or ServerSocketFactory implementations.
#
#ssl.SocketFactory.provider=
#ssl.ServerSocketFactory.provider=


Appendix B: Login Configuration Files

A login configuration file contains one or more LoginContext application names which have the following form:
Application {
    LoginModule Flag ModuleOptions;
    < more LoginModule entries >
    LoginModule Flag ModuleOptions;
};
Login configuration files are located using the login.config.url.n security property found in the java.security file. For more information about this property and the location of the java.security file, see Appendix A.

The Flag value controls the overall behavior as authentication proceeds down the stack. The following represents a description of the valid values for Flag and their respective semantics:

  1. Required

  2. The LoginModule is required to succeed.
    If it succeeds or fails, authentication still continues to proceed down the LoginModule list.
  3. Requisite

  4. The LoginModule is required to succeed.
    If it succeeds, authentication continues down the LoginModule list.
    If it fails, control immediately returns to the application (authentication does not proceed down the LoginModule list).
  5. Sufficient

  6. The LoginModule is not required to succeed.
    If it does succeed, control immediately returns to the application (authentication does not proceed down the LoginModule list).
    If it fails, authentication continues down the LoginModule list.
  7. Optional

  8. The LoginModule is not required to succeed.
    If it succeeds or fails, authentication still continues to proceed down the LoginModule list.
The overall authentication succeeds only if all Required and Requisite LoginModules succeed. If a SufficientLoginModule is configured and succeeds, then only the Required and Requisite LoginModules prior to that Sufficient LoginModule need to have succeeded for the overall authentication to succeed. If no Required or Requisite LoginModules are configured for an application, then at least one Sufficient or OptionalLoginModule must succeed.

Sample Configuration File:

/*  Sample Configuration File  */

Login1 {
   com.ibm.security.auth.module.SampleLoginModule required debug=true;
};

Login2 {
   com.ibm.security.auth.module.SampleLoginModule required;
   com.ibm.security.auth.module.JAASLoginModule sufficient;
   ibm.loginModules.SmartCard requisite debug=true;
   ibm.loginModules.Kerberos optional debug=true;
};
Note: the Flags are not case sensitive. REQUISITE = requisite = Requisite.

Login1 only has one LoginModule which is an instance of the class com.ibm.security.auth.module.SampleLoginModule. Therfore, a LoginContext associated with Login1 will have a successful authentication if and only if its lone module successfully authenticates. The Required flag is trivial in this example; flag values have a relevant effect on authentication when two or more modules are present.

Login2 is easier to explain with a table.

Login2 Authentication Status
SampleLoginModule required pass pass pass pass fail fail fail fail
JAASLoginModule 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 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.


Appendix C: Authorization Policy File

In case there weren't enough examples of Principal-based JAAS Policy grant blocks above, here are some more (Unix format).
// SAMPLE JAAS POLICY FILE:  java.auth.policy

// The following permissions are granted to Principal 'Pooh' and all codesource:

grant Principal com.ibm.security.Principal "Pooh" {
   permission javax.security.auth.AuthPermission "setPolicy";
   permission java.util.PropertyPermission "java.home", "read";
   permission java.util.PropertyPermission "user.home", "read";
   permission java.io.FilePermission "/usr/foo/jaas.txt", "read";
};

// The following permissions are granted to Principal 'Pooh' AND 'Eyeore'
// and CodeSource signedBy "DrSecure":

grant signedBy "DrSecure"
      Principal com.ibm.security.Principal "Pooh",
      Principal com.ibm.security.Principal "Eyeore" {
   permission javax.security.auth.AuthPermission "modifyPublicCredentials";
   permission javax.security.auth.AuthPermission "modifyPrivateCredentials";
   permission java.net.SocketPermission "us.ibm.com", "connect,accept,resolve";
   permission java.net.SocketPermission "griffin.ibm.com", "accept";
};

// The following permissions are granted to Principal 'Pooh' AND 'Eyeore' AND
// 'Piglet' and CodeSource from the /usr/jaas directory signed by "kent" and "bruce':

grant codeBase "file:/usr/jaas/*",
      signedBy "kent, bruce",
      Principal com.ibm.security.Principal "Pooh",
      Principal com.ibm.security.Principal "Eyeore",
          Principal com.ibm.security.Principal "Piglet"  {
   permission javax.security.auth.AuthPermission "getSubject";
   permission java.security.SecurityPermission "printIdentity";
   permission java.net.SocketPermission "guapo.ibm.com", "accept";
};

Appendix D: ThreadSubject

Applicable Platforms:

NT, Windows 2000, Windows 2000 64 Bit, and OS/390.

Description of Functionality:

This is an extension to the normal Subject.doAs. ThreadSubject.doAs basically replaces the current underlying OS's thread userid with the one in the passed in subject. This allows OS security checking to be done using the subject userid versus a possible different userid that is associated with the thread.

The methods used to invoke ThreadSubject.doAs are the same as the ones for Subject.doAs:

    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;

    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;
The above methods are utilized in the same manner as Subject.doAs.

Platform Specifics:

NT, Windows 2000, Windows 2000 64 Bit:
A logged-on system administrator is allowed to authenticate other users when using an ActiveLogon LoginModule, i.e. NTActiveLoginModule or Win64ActiveLoginModule. Then the administrator may impersonate the authenticated user by applying their Subject to a system thread (using the ThreadSubject.doAs and ThreadSubject.doAsPrivileged methods listed above).

When using ThreadSubject methods, please note that the security policy will need to include AuthPermission("threadSubjectDoAs") or AuthPermission("threadSubjectDoAsPrivilege") entries as well as their cousins AuthPermission("doAs") or AuthPermission("doAsPrivileged") from the Subject class.

OS/390:
This function will allow the user identifier that is currently associated with the current thread to be changed to the user identifier associated with the current Subject. In order for this to been done however, there is some SAF (RACF) setup that must be done before this function will work properly. This code makes use of the pthread_security_np service call. This call requires that main thread's userid have the necessary authority to be able to act as a surrogate for other users. Your local SAF (RACF) administrator should be able to enable this environment. The necessary information to set up this environment can be found in z/OS V1R2.0 UNIX System Services Planning  document number GA22-7800-01 in the section called "Defining Servers to Use Thread-Level Security" and in z/OS V1R2.0 SecureWay Security Server RACF Security Administrator's Guide  document number SA22-7683-01 in the section titled "z/OS UNIX Application Considerations".

Appendix E: SAFPermission for OS/390

This class allows a program to do SAF (RACF) like security checking. A SAFPermission contains a SecurityClass, an entityName and an access. Basically, you supply these three values using one of the following constructors and the values are used by SAF (RACF) to determine if the user has the necessary access. The following are the constructors for this class:
    public SAFPermission(String securityClass,
                         String entityName,
                         Integer access)

    public SAFPermission(String securityClass,
                         String entityName)
 
    public SAFPermission(String entityName,
                         Integer access)

    public SAFPermission(String entityName)
The first constructor creates a new SAFPermission with the specified securityClass, entityName, and access.

 The second one creates a new SAFPermission with the specified securityClass, entityName and an implied access of SAFPermission.__READ_RESOURCE.

 The third constructor uses the specified entityName and access, as well as an implied securityClass of JAVA to create a new SAFPermission object.

 The last one creates a new object of class SAFPermission with an implied securityClass of JAVA, a entityName as specified and an implied access of SAFPermission.__READ_RESOURCE.

 The securityClass parameter is the security class to check with, the entityName parameter is the entity for which the check is to be done. These parameters can have any valid SAF (RACF) value.

The access parameter is the required access and must be one of the following:

    SAFPermission.__READ_RESOURCE

    SAFPermission.__UPDATE_RESOURCE

    SAFPermission.__CONTROL_RESOURCE

    SAFPermission.__ALTER_RESOURCE
A sample of using the above can be found in the {$java.home}/demo/jaas or below:
    java.lang.SecurityManager sm = System.getSecurityManager();
    sm.checkPermission( new SAFPermission("FACILITY",
                                          "BPX.SERVER",
                                          SAFPermission.__UPDATE_RESOURCE ));
The code above creates a new SAFPermission and then uses the current SecurityManager to determine if the current subject has that permission. This will return an AccessControlException if the subject does not have the required access.

Policy Requirements for SAFPermission:

This class requires some entries in the java.policy file.

The first addition allows all code source to be able to ask checkPermission questions of a SAFPermission:

grant codeBase "file:/-" {
   permission com.ibm.security.auth.SAFPermission "*", "*";
};
The above could be changed to limit the codeBases that have ability to use SAFPermission by changing "file:/-" to the needed codebase or directory.

The following permissions need to be added to each grant block as well:

permission java.lang.RuntimePermission "loadLibrary.SecurityServices";
permission java.io.FilePermission ":${java.home}/lib/ext/-", "read";
permission java.util.PropertyPermission "java.execsuffix", "read";
The above are required for lower level function calls that SAFPermission makes.
A sample of a policy file that contains the above can also be found in {$java.home}/demo/jaas.


Appendix F: OS/390 LoginModule

Name of the LoginModule :

The OS390LoginModule is in package com.ibm.security.auth.module.

Notes about LoginModule :

There are two types of logins that are allowed with this LoginModule: passive and active login.

If no CallbackHandler was specified on the creation of the LoginContext that is utilizing the OS390LoginModule, then the underlying operating system is queried for the current identity which is used to create a Subject. This is a passive login.

However, if a CallbackHandler was specified, then this OS390LoginModule drives a NameCallback and a PasswordCallback to get user information which in turn is used in a SAF (RACF) call to verify the userid and password. After the userid and password are verified, a Subject is created with this information. This is an active login. The Callback classes are part of the javax.security.auth.callback package.

Also, the OS390LoginModule ignores the sharedState parameter. The JAAS HelloWorld example code can be modified to use this LoginModule by using the helloOS390.config file instead of using the hello.config file. Look at {$java.home}/demo/jaas for this configuraiton file.



© IBM Corporation 1999, 2004. All Rights Reserved

© 1996-2004 Sun Microsystems, Inc. All Rights Reserved.




Back to top


Document options

Document options requiring JavaScript are not displayed


Related information
General SDK FAQs
Newsgroups