Tuesday Sep 25, 2007

A standalone OpenSSO client

OpenSSO has a server part (deployed behind a /fam URI or similar) and a client part (e.g. a J2EE agent, or the OpenID extension). In any case you have ensure that the AMConfig.properties for each part do correspond w.r.t. encryption keys, agent IDs etc. Since debugging an J2EE agent or even OpenID extension might be unfeasible (at least as a first step), I use a stand-alone client which sources the AMAgent.properties used by e.g. the OpenID extension.

The following code is example and works well for OpenSSO, Sun Java System Access Manager (7.0 and 7.1) all deployed in realm mode.

To build the JAR, make sure that you include the OpenSSO Client SDK as well as the servlet.jar to your (NetBeans) project.

/\*
 \* OpenSSOConnect.java
 \*
 \* Created on November 2, 2006, 11:18 AM
 \*
 \* To change this template, choose Tools | Template Manager
 \* and open the template in the editor.
 \*/

/\*\*
 \*
 \* @author steffo
 \*/


// OpenSSO installation has a default realm 'init8' as well as an authentication chain 'init8'

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.ChoiceCallback;
import javax.security.auth.callback.ConfirmationCallback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.TextInputCallback;
import javax.security.auth.callback.TextOutputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

import netscape.ldap.util.DN;

import com.iplanet.am.util.SystemProperties;
import com.iplanet.sso.SSOToken;
import com.sun.identity.authentication.AuthContext;
import com.sun.identity.idm.AMIdentity;
import com.sun.identity.idm.AMIdentityRepository;
import com.sun.identity.idm.IdRepoException;
import com.sun.identity.idm.IdSearchControl;
import com.sun.identity.idm.IdSearchOpModifier;
import com.sun.identity.idm.IdSearchResults;
import com.sun.identity.idm.IdType;
import com.sun.identity.idm.IdUtils;
import com.sun.identity.security.AdminTokenAction;


import com.sun.identity.authentication.spi.AuthLoginException;


public class OpenSSOConnect {

	public static void main(String[] argv) {
		boolean remote = false;
		if (argv.length > 0) {
			String r = argv[0];
			if (r.equalsIgnoreCase("remote")) {
				remote = true;
			}
		}
		Properties props = new Properties();

		try {
                        //Point this to the AMConfig.properties, you want to check
			FileInputStream amconfig = new FileInputStream("/Users/steffo/Projekte/OpenSSO/OpenID-Provider/src/opensso/extensions/openid/provider/resources/AMConfig.properties");
			
			props.load(amconfig);
		} catch (IOException e) {
			System.out.println("AMConfig.properties was not found");
		}

		props.setProperty("com.iplanet.services.debug.level", "message");
                props.setProperty("com.iplanet.am.naming.ignoreNamingService", "true");
		
                //remote=true;
		if (remote) {
			props.setProperty("com.iplanet.am.sdk.package", "com.iplanet.am.sdk.remote");
		} else {
			props.setProperty(AdminTokenAction.AMADMIN_MODE, "true");
		}
		System.out.println("Properties set");
		SystemProperties.initializeProperties(props);
		try {
			SSOToken token = getSSOToken();
			System.out.println("Getting AMIdentityRepository object");

			AMIdentityRepository idrepo = new AMIdentityRepository(token, "init8");
                        
                       

			System.out.println("Using TOKEN to get AMIdentity object " + "and read attrs");
			AMIdentity tmpId = IdUtils.getIdentity(token);
			System.out.println("Calling Attributes getting all attributes: " + tmpId.getAttributes());
						

		} catch (Exception ex) {
			ex.printStackTrace();
		}
		System.exit(0);
	}

	public static SSOToken getSSOToken() throws Exception {
                //We created a user 'steffo' with credenials 'password'
		return getSSOToken("init8", "steffo", "password");

	}

	protected static SSOToken getSSOToken(String org, String uid,
			String password) throws Exception {

		AuthContext ac = new AuthContext(org);
		ac.login(AuthContext.IndexType.SERVICE, "init8");
		Callback[] callbacks = null;
		if (ac.hasMoreRequirements()) {
			callbacks = ac.getRequirements();

			if (callbacks != null) {
				try {
					addLoginCallbackMessage(callbacks, uid, password);
					ac.submitRequirements(callbacks);
				} catch (Exception e) {
					debugMessage("Login failed!!");
                                        debugMessage("--> " + ac.getLoginException().getMessage());
					e.printStackTrace();
					return null;
				}
			}
		}
		if (ac.getStatus() == AuthContext.Status.SUCCESS) {
			debugMessage("Login success!!");
		} else if (ac.getStatus() == AuthContext.Status.FAILED) {
			debugMessage("Login has failed!!");
                        debugMessage("--> " + ac.getLoginException().getMessage());
		} else if( ac.getStatus() == AuthContext.Status.IN_PROGRESS ) {
                        // This may happen when the password is about to expire and must be reset.
                        // Analyze the error message to be sure what is going on.
			debugMessage( "Login is in progress !" );
                        //debugMessage("--> " + ac.getLoginException().getMessage());
                        if( ac.hasMoreRequirements() ) {
                                callbacks = ac.getRequirements();
                                if( callbacks != null ) {
                                    debugMessage( "Callbacks for new password will be processed !" );
                                    try {
                                            addNewPasswordCallbackMessage( callbacks, uid, password, "Geheim03" );
                                            ac.submitRequirements( callbacks );
                                    } catch( Exception e ) {
                                            debugMessage( "Login failed while processing new password callbacks." );
                                            debugMessage("--> " + ac.getLoginException().getMessage());
                                            e.printStackTrace();
                                            return null;
                                    }
                                }
                        }
                    if( ac.getStatus() == AuthContext.Status.SUCCESS )
                            debugMessage( "Login success after switch to new password!" );                           
                    else {
                            debugMessage( "Login failed after switch to new password!" );  
                            debugMessage("--> " + ac.getLoginException().getMessage());
                            }

                }
                   else {
			debugMessage("Unknown status: " + ac.getStatus());
                        debugMessage("--> " + ac.getLoginException().getMessage());
		}

		SSOToken token = ac.getSSOToken();
		return token;

	}

	// Get user's inputs and set them to callback array.
	static void addLoginCallbackMessage(Callback[] callbacks, String uid,
			String password) throws UnsupportedCallbackException {
		debugMessage("begin addLoginCallbackMessage()");
		int i = 0;
		try {
			for (i = 0; i < callbacks.length; i++) {
				if (callbacks[i] instanceof TextOutputCallback) {
					debugMessage("Got TextOutputCallback");
					// Display the message according to the specified type
					TextOutputCallback toc = (TextOutputCallback) callbacks[i];
					switch (toc.getMessageType()) {
					case TextOutputCallback.INFORMATION:
						debugMessage(toc.getMessage());
						break;
					case TextOutputCallback.ERROR:
						debugMessage("ERROR: " + toc.getMessage());
						break;
					case TextOutputCallback.WARNING:
						debugMessage("WARNING: " + toc.getMessage());
						break;
					default:
						debugMessage("Unsupported message type: "
								+ toc.getMessageType());
					}
				} else if (callbacks[i] instanceof NameCallback) {
					debugMessage("Got NameCallback");
					NameCallback nc = (NameCallback) callbacks[i];
					nc.setName(uid);
				} else if (callbacks[i] instanceof PasswordCallback) {
					debugMessage("Got PasswordCallback");
					PasswordCallback pc = (PasswordCallback) callbacks[i];
					pc.setPassword(new String(password).toCharArray());
				} else if (callbacks[i] instanceof TextInputCallback) {
					debugMessage("Got TextInputCallback");
					// prompt for text input
					TextInputCallback tic = (TextInputCallback) callbacks[i];
					// ignore the provided defaultValue
					System.err.print(tic.getPrompt());
					System.err.flush();
					tic.setText((new BufferedReader(new InputStreamReader(
							System.in))).readLine());

				} else if (callbacks[i] instanceof ChoiceCallback) {
					debugMessage("Got ChoiceCallback");
					// prompt for choice input
					ChoiceCallback cc = (ChoiceCallback) callbacks[i];
					System.err.print(cc.getPrompt());

					String[] strChoices = cc.getChoices();
					for (int j = 0; j < strChoices.length; j++) {
						System.err
								.print("choice[" + j + "] : " + strChoices[j]);
					}
					System.err.flush();
					cc.setSelectedIndex(Integer.parseInt((new BufferedReader(
							new InputStreamReader(System.in))).readLine()));
				}
			}
		} catch (Exception e) {
			throw new UnsupportedCallbackException(callbacks[i],
					"Callback exception: " + e);
		}
	}
        
        static void addNewPasswordCallbackMessage(  Callback[] callbacks,
                                                    String uid,
                                                    String oldPassword,
                                                    String newPassword ) throws UnsupportedCallbackException
        {
		int pwdCount    = 0;
		int i           = 0;
		try {
			for (i = 0; i < callbacks.length; i++) {
				if (callbacks[i] instanceof TextOutputCallback) {
					debugMessage( "Got TextOutputCallback while setting new password." );
					// simply display the message
					TextOutputCallback toc = (TextOutputCallback) callbacks[i];
					debugMessage(toc.getMessage() + " :" + toc.getMessage() );
				} else if (callbacks[i] instanceof NameCallback) {
					debugMessage( "Got NameCallback while setting new password - this should not happen !" );
                                        debugMessage( "Maybe you hit the next login module." );
				} else if (callbacks[i] instanceof PasswordCallback) {
					debugMessage( "Got PasswordCallback while setting new password." );
                                        
					PasswordCallback pc = (PasswordCallback) callbacks[i];

                                        // set first password callback with value of old password, the others with the new one
                                        if( pwdCount == 0 )
                                            pc.setPassword( new String( oldPassword ).toCharArray() );
                                        else
                                            pc.setPassword( new String( newPassword ).toCharArray() );
                                        
                                        pwdCount++;
                                            
				} else if (callbacks[i] instanceof ConfirmationCallback) {
					debugMessage( "Got ConfirmationCallback while setting new password !" );
					ConfirmationCallback cc = (ConfirmationCallback) callbacks[i];
                                        // "0" is the index of SUBMIT
                                        cc.setSelectedIndex( 0 );
				} else if (callbacks[i] instanceof TextInputCallback) {
					debugMessage( "Got TextInputCallback while setting new password - this should not happen !" );
				} else if (callbacks[i] instanceof ChoiceCallback) {
					debugMessage( "Got ChoiceCallback while setting new password - this should not happen !" );
				}
			}
		} catch( Exception e ) {
			throw new UnsupportedCallbackException( callbacks[i], "Callback exception: " + e );
		}
	}

	static void debugMessage(String msg) {
		System.out.println(msg);
	}

}

About

steffo

Search

Top Tags
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today