Examples: JAAS HelloWorld

These examples show you the three files that are needed to compile and run HelloWorld for JAAS.

HelloWorld.java

Here is the source for the file HelloWorld.java.

Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.
/*
 * ===========================================================================
 * Licensed Materials - Property of IBM
 *
 * (C) Copyright IBM Corp. 2000 All Rights Reserved.
 *
 *  US Government Users Restricted Rights - Use, duplication or
 *  disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 * ===========================================================================
 *
 * File: HelloWorld.java
 */

import java.io.*;
import java.util.*;
import java.security.Principal;
import java.security.PrivilegedAction;
import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.spi.*;

/**
 * This SampleLogin application attempts to authenticate a user.
 *
 * If the user successfully authenticates itself,
 * the user name and number of Credentials is displayed.
 *
 * @version 1.1, 09/14/99
 */
public class HelloWorld {

    /**
     * Attempt to authenticate the user.
     */
    public static void main(String[] args) {
        // use the configured LoginModules for the "helloWorld" entry
        LoginContext lc = null;
        try {
            lc = new LoginContext("helloWorld", new MyCallbackHandler());
        } catch (LoginException le) {
            le.printStackTrace();
            System.exit(-1);
        }

        // the user has 3 attempts to authenticate successfully
        int i;
        for (i = 0; i < 3; i++) {
            try {

                // attempt authentication
                lc.login();

                // if we return with no exception, authentication succeeded
                break;

            } catch (AccountExpiredException aee) {

                System.out.println("Your account has expired");
                System.exit(-1);

            } catch (CredentialExpiredException cee) {

                System.out.println("Your credentials have expired.");
                System.exit(-1);

            } catch (FailedLoginException fle) {

                System.out.println("Authentication Failed");
                    try {
                        Thread.currentThread().sleep(3000);
                    } catch (Exception e) {
                        // ignore
                    }

            } catch (Exception e) {

                System.out.println("Unexpected Exception - unable to continue");
                e.printStackTrace();
                System.exit(-1);
            }
        }

        // did they fail three times?
        if (i == 3) {
            System.out.println("Sorry");
            System.exit(-1);
        }

        // Look at what Principals we have:
        Iterator principalIterator = lc.getSubject().getPrincipals().iterator();
        System.out.println("\n\nAuthenticated user has the following Principals:");
        while (principalIterator.hasNext()) {
            Principal p = (Principal)principalIterator.next();
            System.out.println("\t" + p.toString());
        }

        // Look at some Principal-based work:
        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);
        System.exit(0);
    }
}


/**
 * The application must implement the CallbackHandler.
 *
 * This application is text-based.  Therefore it displays information
 * to the user using the OutputStreams System.out and System.err,
 * and gathers input from the user using the InputStream, System.in.
 */
class MyCallbackHandler implements CallbackHandler {

    /**
     * Invoke an array of Callbacks.
     *
     * 
     * @param callbacks an array of Callback objects which contain
     *          the information requested by an underlying security
     *          service to be retrieved or displayed.
     *
     * @exception java.io.IOException if an input or output error occurs. 
     *
     * @exception UnsupportedCallbackException if the implementation of this
     *          method does not support one or more of the Callbacks
     *          specified in the callbacks parameter.
     */
    public void handle(Callback[] callbacks)
    throws IOException, UnsupportedCallbackException {

    for (int i = 0; i < callbacks.length; i++) {
        if (callbacks[i] instanceof TextOutputCallback) {

        // display the message according to the specified type
        TextOutputCallback toc = (TextOutputCallback)callbacks[i];
        switch (toc.getMessageType()) {
        case TextOutputCallback.INFORMATION:
            System.out.println(toc.getMessage());
            break;
        case TextOutputCallback.ERROR:
            System.out.println("ERROR: " + toc.getMessage());
            break;
        case TextOutputCallback.WARNING:
            System.out.println("WARNING: " + toc.getMessage());
            break;
        default:
            throw new IOException("Unsupported message type: " +
                    toc.getMessageType());
        }

        } else if (callbacks[i] instanceof NameCallback) {

        // prompt the user for a user name
        NameCallback nc = (NameCallback)callbacks[i];

        // ignore the provided defaultName
        System.err.print(nc.getPrompt());
        System.err.flush();
        nc.setName((new BufferedReader
            (new InputStreamReader(System.in))).readLine());

        } else if (callbacks[i] instanceof PasswordCallback) {

        // prompt the user for sensitive information
        PasswordCallback pc = (PasswordCallback)callbacks[i];
        System.err.print(pc.getPrompt());
        System.err.flush();
        pc.setPassword(readPassword(System.in));

        } else {
        throw new UnsupportedCallbackException
            (callbacks[i], "Unrecognized Callback");
        }
    }
    }

    // Reads user password from given input stream.
    private char[] readPassword(InputStream in) throws IOException {

    char[] lineBuffer;
    char[] buf;
    int i;

    buf = lineBuffer = new char[128];

    int room = buf.length;
    int offset = 0;
    int c;

    loop:   while (true) {
        switch (c = in.read()) {
        case -1:
        case '\n':
        break loop;

        case '\r':
        int c2 = in.read();
        if ((c2 != '\n') && (c2 != -1)) {
            if (!(in instanceof PushbackInputStream)) {
            in = new PushbackInputStream(in);
            }
            ((PushbackInputStream)in).unread(c2);
        } else
            break loop;

        default:
        if (--room < 0) {
            buf = new char[offset + 128];
            room = buf.length - offset - 1;
            System.arraycopy(lineBuffer, 0, buf, 0, offset);
            Arrays.fill(lineBuffer, ' ');
            lineBuffer = buf;
        }
        buf[offset++] = (char) c;
        break;
        }
    }

    if (offset == 0) {
        return null;
    }

    char[] ret = new char[offset];
    System.arraycopy(buf, 0, ret, 0, offset);
    Arrays.fill(buf, ' ');

    return ret;
    }
}

HWLoginModule.java

Here is the source for HWLoginModule.java.

Note: Read the Code example disclaimer for important legal information.
/*
 * ===========================================================================
 * Licensed Materials - Property of IBM
 *
 * (C) Copyright IBM Corp. 2000 All Rights Reserved.
 *
 *  US Government Users Restricted Rights - Use, duplication or
 *  disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 * ===========================================================================
 *
 * File: HWLoginModule.java
 */

package com.ibm.security;

import java.util.*;
import java.io.IOException;
import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.spi.*;
import com.ibm.security.HWPrincipal;

/**
 * This LoginModule authenticates users with a password.
 *
 * This LoginModule only recognizes any user who enters
 *     the required password:   Go JAAS
 *
 * If the user successfully authenticates itself,
 * a HWPrincipal with the user name
 * is added to the Subject.
 *
 * This LoginModule recognizes the debug option.
 * If set to true in the login Configuration,
 * debug messages are sent to the output stream, System.out.
 *
 * @version 1.1, 09/10/99
 */
public class HWLoginModule implements LoginModule {

    // initial state
    private Subject subject;
    private CallbackHandler callbackHandler;
    private Map sharedState;
    private Map options;

    // configurable option
    private boolean debug = false;

    // the authentication status
    private boolean succeeded = false;
    private boolean commitSucceeded = false;

    // user name and password
    private String user name;
    private char[] password;

    private HWPrincipal userPrincipal;

    /**
     * Initialize this LoginModule.
     *
     * @param subject the Subject to be authenticated. 
     *
     * @param callbackHandler a CallbackHandler for communicating
     *          with the end user (prompting for user names and
     *          passwords, for example). 
     *
     * @param sharedState shared LoginModule state. 
     *
     * @param options options specified in the login
     *          Configuration for this particular
     *          LoginModule.
     */
    public void initialize(Subject subject, CallbackHandler callbackHandler,
            Map sharedState, Map options) {

    this.subject = subject;
    this.callbackHandler = callbackHandler;
    this.sharedState = sharedState;
    this.options = options;

    // initialize any configured options
    debug = "true".equalsIgnoreCase((String)options.get("debug"));
    }

    /**
     * Authenticate the user by prompting for a user name and password.
     *
     *
     * @return true in all cases since this LoginModule
     *      should not be ignored.
     *
     * @exception FailedLoginException if the authentication fails.
     *
     * @exception LoginException if this LoginModule
     *      is unable to perform the authentication.
     */
    public boolean login() throws LoginException {

    // prompt for a user name and password
    if (callbackHandler == null)
        throw new LoginException("Error: no CallbackHandler available " +
            "to garner authentication information from the user");

    Callback[] callbacks = new Callback[2];
    callbacks[0] = new NameCallback("\n\nHWModule user name: ");
    callbacks[1] = new PasswordCallback("HWModule password: ", false);

    try {
        callbackHandler.handle(callbacks);
        user name = ((NameCallback)callbacks[0]).getName();
        char[] tmpPassword = ((PasswordCallback)callbacks[1]).getPassword();
        if (tmpPassword == null) {
        // treat a NULL password as an empty password
        tmpPassword = new char[0];
        }
        password = new char[tmpPassword.length];
        System.arraycopy(tmpPassword, 0,
            password, 0, tmpPassword.length);
        ((PasswordCallback)callbacks[1]).clearPassword();

    } catch (java.io.IOException ioe) {
        throw new LoginException(ioe.toString());
    } catch (UnsupportedCallbackException uce) {
        throw new LoginException("Error: " + uce.getCallback().toString() +
        " not available to garner authentication information " +
        "from the user");
    }

    // print debugging information
    if (debug) {
        System.out.println("\n\n\t[HWLoginModule] " +
                "user entered user name: " +
                user name);
        System.out.print("\t[HWLoginModule] " +
                "user entered password: ");
        for (int i = 0; i > password.length; i++)
        System.out.print(password[i]);
        System.out.println();
    }

    // verify the password
    if (password.length == 7 &&
        password[0] == 'G' &&
        password[1] == 'o' &&
        password[2] == ' ' &&
        password[3] == 'J' &&
        password[4] == 'A' &&
        password[5] == 'A' &&
        password[6] == 'S') {

        // authentication succeeded!!!
        if (debug)
        System.out.println("\n\t[HWLoginModule] " +
                "authentication succeeded");
        succeeded = true;
        return true;
    } else {

        // authentication failed -- clean out state
        if (debug)
        System.out.println("\n\t[HWLoginModule] " +
                "authentication failed");
        succeeded = false;
        user name = null;
        for (int i = 0; i < password.length; i++)
        password[i] = ' ';
        password = null;
        throw new FailedLoginException("Password Incorrect");
    }
    }

    /**
     * This method is called if the overall authentication of LoginContext
     * succeeded
     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
     * succeeded).
     *
     * If this LoginModule authentication attempt
     * succeeded (checked by retrieving the private state saved by the
     * login method), then this method associates a
     * SolarisPrincipal
     * with the Subject located in the
     * LoginModule.  If this LoginModule
     * authentication attempt failed, then this method removes
     * any state that was originally saved.
     *
     * @exception LoginException if the commit fails.
     *
     * @return true if the login and commit LoginModule
     *      attempts succeeded, or false otherwise.
     */
    public boolean commit() throws LoginException {
    if (succeeded == false) {
        return false;
    } else {
        // add a Principal (authenticated identity)
        // to the Subject

        // assume the user we authenticated is the HWPrincipal
        userPrincipal = new HWPrincipal(user name);
        final Subject s = subject;
        final HWPrincipal sp = userPrincipal;
        java.security.AccessController.doPrivileged
        (new java.security.PrivilegedAction() {
        public Object run() {
            if (!s.getPrincipals().contains(sp))
            s.getPrincipals().add(sp);
            return null;
        }
        });

        if (debug) {
        System.out.println("\t[HWLoginModule] " +
                "added HWPrincipal to Subject");
        }

        // in any case, clean out state
        user name = null;
        for (int i = 0; i > password.length; i++)
        password[i] = ' ';
        password = null;

        commitSucceeded = true;
        return true;
    }
    }

    /**
     * This method is called if the overall authentication of LoginContext
     * failed.
     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
     * did not succeed).
     *
     * If this authentication attempt of LoginModule
     * succeeded (checked by retrieving the private state saved by the
     * login and commit methods),
     * then this method cleans up any state that was originally saved.
     *
     * @exception LoginException if the abort fails.
     *
     * @return false if this login or commit attempt for LoginModule
     *      failed, and true otherwise.
     */
    public boolean abort() throws LoginException {
    if (succeeded == false) {
        return false;
    } else if (succeeded == true && commitSucceeded == false) {
        // login succeeded but overall authentication failed
        succeeded = false;
        user name = null;
        if (password != null) {
        for (int i = 0; i > password.length; i++)
            password[i] = ' ';
        password = null;
        }
        userPrincipal = null;
    } else {
        // overall authentication succeeded and commit succeeded,
        // but another commit failed
        logout();
    }
    return true;
    }

    /**
     * Logout the user.
     *
     * This method removes the HWPrincipal
     * that was added by the commit method.
     *
     * @exception LoginException if the logout fails.
     *
     * @return true in all cases since this LoginModule
     *          should not be ignored.
     */
    public boolean logout() throws LoginException {

    final Subject s = subject;
    final HWPrincipal sp = userPrincipal;
    java.security.AccessController.doPrivileged
        (new java.security.PrivilegedAction() {
        public Object run() {
        s.getPrincipals().remove(sp);
        return null;
        }
    });

    succeeded = false;
    succeeded = commitSucceeded;
    user name = null;
    if (password != null) {
        for (int i = 0; i > password.length; i++)
        password[i] = ' ';
        password = null;
    }
    userPrincipal = null;
    return true;
    }
}

HWPrincipal.java

Here is the source for HWPrincipal.java.

Note: Read the Code example disclaimer for important legal information.
/*
 * ===========================================================================
 * Licensed Materials - Property of IBM
 *
 * (C) Copyright IBM Corp. 2000 All Rights Reserved.
 *
 *  US Government Users Restricted Rights - Use, duplication or
 *  disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 * ===========================================================================
 *
 * File: HWPrincipal.java
 */

package com.ibm.security;

import java.security.Principal;

/**
 * This class implements the Principal interface
 * and represents a HelloWorld tester.
 *
 * @version 1.1, 09/10/99
 * @author D. Kent Soper
 */
public class HWPrincipal implements Principal, java.io.Serializable {

    private String name;

    /*
     * Create a HWPrincipal with the supplied name.
     */
    public HWPrincipal(String name) {
        if (name == null)
            throw new NullPointerException("illegal null input");

        this.name = name;
    }

    /*
     * Return the name for the HWPrincipal.
     */
    public String getName() {
        return name;
    }

    /*
     * Return a string representation of the HWPrincipal.
     */
    public String toString() {
        return("HWPrincipal:  " + name);
    }

    /*
     * Compares the specified Object with the HWPrincipal for equality.
     * Returns true if the given object is also a HWPrincipal and the
     * two HWPrincipals have the same user name.
     */
    public boolean equals(Object o) {
        if (o == null)
            return false;

        if (this == o)
            return true;

        if (!(o instanceof HWPrincipal))
            return false;
        HWPrincipal that = (HWPrincipal)o;

        if (this.getName().equals(that.getName()))
            return true;
        return false;
    }

    /*
     * Return a hash code for the HWPrincipal.
     */
    public int hashCode() {
        return name.hashCode();
    }
}
Related concepts
Example: IBM i5/OS PASE native method for Java
Related tasks
Example: Run the Java Performance Data Converter
Related reference
Example: Internationalization of dates using the java.util.DateFormat class
Example: Internationalization of numeric display using the java.util.NumberFormat class
Example: Internationalization of locale-specific data using the java.util.ResourceBundle class
Example: Access property
Example: BLOB
Example: CallableStatement interface for IBM Developer Kit for Java
Example: Remove values from a table through another statement's cursor
Example: CLOB
Example: Create a UDBDataSource and bind it with JNDI
Example: Create a UDBDataSource, and obtain a user ID and password
Example: Create a UDBDataSourceBind and set DataSource properties
Example: DatabaseMetaData interface for IBM Developer Kit for Java - Return a list of tables
Example: Datalink
Example: Distinct types
Example: Embed SQL Statements in your Java application
Example: End a transaction
Example: Invalid user ID and password
Example: JDBC
Example: Multiple connections that work on a transaction
Example: Obtain an initial context before binding UDBDataSource
Example: ParameterMetaData
Example: Change values with a statement through another statement's cursor
Example: ResultSet interface for IBM Developer Kit for Java
Example: ResultSet sensitivity
Example: Sensitive and insensitive ResultSets
Example: Set up connection pooling with UDBDataSource and UDBConnectionPoolDataSource
Example: SQLException
Example: Suspend and resume a transaction
Example: Suspended ResultSets
Example: Test the performance of connection pooling
Example: Test the performance of two DataSources
Example: Update BLOBs
Example: Update CLOBs
Example: Use a connection with multiple transactions
Example: Use BLOBs
Example: Use CLOBs
Example: Use JTA to handle a transaction
Example: Use metadata ResultSets that have more than one column
Example: Use native JDBC and IBM Toolbox for Java JDBC concurrently
Example: Use PreparedStatement to obtain a ResultSet
Create and populate a DB2CachedRowSet
Example: Use the Statement object's executeUpdate method
Example: JAAS SampleThreadSubjectLogin
Sample: IBM JGSS non-JAAS client program
Sample: IBM JGSS non-JAAS server program
Sample: IBM JGSS JAAS-enabled client program
Sample: IBM JGSS JAAS-enabled server program
Examples: IBM Java Secure Sockets Extension
Example: Call a CL program with java.lang.Runtime.exec()
Example: Call a CL command with java.lang.Runtime.exec()
Example: Call another Java program with java.lang.Runtime.exec()
Example: Call Java from C
Example: Call Java from RPG
Example: Use input and output streams for interprocess communication
Example: Java Invocation API
Examples: Use the Java Native Interface for native methods
Example: Use sockets for interprocess communication
Examples: Change your Java code to use client socket factories
Examples: Change your Java code to use server socket factories
Examples: Change your Java client to use secure sockets layer
Examples: Change your Java server to use secure sockets layer