Sun OpenSSO Enterprise 8.0 Developer's Guide

Initiating Authentication with the Authentication Service API

The OpenSSO Enterprise Authentication Service can be accessed by a web browser, an application using the authentication client API or any client that correctly implements the Authentication Service messaging interfaces. The com.sun.identity.authentication package contains the authentication client interfaces and classes with which a custom application can be enhanced to achieve authenticated access to the OpenSSO Enterprise Authentication Service. The custom application, running either locally or remotely to OpenSSO Enterprise, can initiate an authentication process, submit required credentials and retrieve the single sign-on (SSO) session token for itself or a user. The authentication client API starts the authentication process, and the Authentication Service responds with a set of requirements such as user ID and password. The appropriate credentials are returned to the Authentication Service. This back and forth communication between the custom application (with implemented API) and the Authentication Service continues until all requirements have been met and authentication has been determined to be successful or not.

The first step in the code sequence for the authentication process is to instantiate the com.sun.identity.authentication.AuthContext class which will create a new AuthContext object for each authentication request. Since OpenSSO Enterprise can handle multiple realms, AuthContext should be initialized, at the least, with the name of the realm to which the requestor is authenticating. Once an AuthContext object has been created, the login() method is called indicating to the server what method of authentication is desired. The getRquirements() method returns an array of Callback objects that correspond to the credentials the user must pass to the Authentication Service. These objects are requested by the authentication plug-ins, and are usually displayed to the user as login requirement screens. For example, if the requested user is authenticating to an organization configured for LDAP authentication only, the server will respond with the LDAP login requirement screen to supply a user name and a password. The code must then loop by calling the hasMoreRequirements() method until the required credentials have been entered. Once entered, the credentials are submitted back to the server with the submitRequirements() method. The final step is to make a getStatus() method call to determine if the authentication was successful. If successful, the caller obtains a session token for the user; if not, a LoginException is thrown.

The following code sample illustrates how to authenticate users with user name and password credentials and obtain the session token using getSSOToken().


Example 1–1 Authentication Code Sample

import com.iplanet.sso.SSOToken;
import com.sun.identity.authentication.AuthContext;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;

public class TokenUtils {
    public static SSOToken getSessionToken(String realmName, String userId, 
        String password) throws Exception {
        AuthContext ac = null;
        try {
            if (realmName == null || realmName.length() == 0) {
                realmName = "/";
            }
            ac = new AuthContext(realmName);
            ac.login();
        } catch (LoginException le) {
            le.printStackTrace();
            return null;
        }

        try { 
            Callback[] callbacks = null;
            // Get the information requested by the plug-ins
            if (ac.hasMoreRequirements()) {
                callbacks = ac.getRequirements();

                if (callbacks != null) {
                    addLoginCallbackMessage(callbacks, userId, password);
                    ac.submitRequirements(callbacks);

                    if (ac.getStatus() == AuthContext.Status.SUCCESS) {
                        System.out.println("Auth success");
                    } else if (ac.getStatus() == AuthContext.Status.FAILED) {
                        System.out.println("Authentication has FAILED");
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return ac.getSSOToken();
    } 

    static void addLoginCallbackMessage(Callback[] callbacks, String userId,
        String password) 
         throws UnsupportedCallbackException 
    {
        int i = 0;
        try {
            for (i = 0; i < callbacks.length; i++) {
                if (callbacks[i] instanceof NameCallback) {
                    NameCallback nc = (NameCallback) callbacks[i];
                    nc.setName(userId);
                } else if (callbacks[i] instanceof PasswordCallback) {
                    PasswordCallback pc = (PasswordCallback) callbacks[i];
                    pc.setPassword(password.toCharArray());
                }
            }
        } catch (Exception e) {
             throw new UnsupportedCallbackException(callbacks[i], 
                   "Callback exception: " + e);
        }
    }
}


Note –

Because the Authentication Service is built using the Java Authentication and Authorization Service (JAAS) framework, the Authentication Service client API can invoke any authentication modules written using the JAAS API. JAAS enables services to authenticate and enforce access controls upon users. It implements a Java version of the standard Pluggable Authentication Module (PAM) framework. Because of this architecture, any custom JAAS authentication module (as well as those modules built specifically for OpenSSO Enterprise) will work with the Authentication Service. For more information on JAAS, see the Java Authentication And Authorization Service Reference Guide and http://java.sun.com/products/jaas/.