I noticed that this is no longer up to date. The final solution was to use the Java SDK that OpenAM provides.
This is the starting point: http://openam.forgerock.org/openam-documentation/openam-doc-source/doc/dev-guide/index/chap-jdk.html
1) add all of the jar files that come with this SDK to your web application. 2) Change your servlet (or heavy client) to have the following code:
private void addLoginCallbackMessage(LoginCredentialsBean loginBean, Callback [] callbacks)
throws UnsupportedCallbackException
{
int i = 0;
try
{
for (i = 0; i < callbacks.length; i++)
{
if (callbacks[i] instanceof TextOutputCallback)
{
handleTextOutputCallback((TextOutputCallback) callbacks[i]);
}
else if (callbacks[i] instanceof NameCallback)
{
handleNameCallback(loginBean.getUsername(), (NameCallback) callbacks[i]);
}
else if (callbacks[i] instanceof PasswordCallback)
{
handlePasswordCallback(loginBean.getPassword(), (PasswordCallback) callbacks[i]);
}
else if (callbacks[i] instanceof TextInputCallback)
{
handleTextInputCallback((TextInputCallback) callbacks[i]);
}
else if (callbacks[i] instanceof ChoiceCallback)
{
handleChoiceCallback((ChoiceCallback) callbacks[i]);
}
}
}
catch (IOException e)
{
e.printStackTrace();
throw new UnsupportedCallbackException(callbacks[i], e.getMessage());
}
}
private void handleTextOutputCallback(TextOutputCallback toc)
{
System.out.println("Got TextOutputCallback");
// display the message according to the specified type
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:
System.out.println("Unsupported message type: " +
toc.getMessageType());
}
}
private void handleNameCallback(String name, NameCallback nc)
throws IOException
{
nc.setName(name);
}
private void handleTextInputCallback(TextInputCallback tic)
throws IOException
{
// not supported for server side
// prompt for text input
}
private void handlePasswordCallback(String password, PasswordCallback pc)
throws IOException
{
// prompt the user for sensitive information
pc.setPassword(password.toCharArray());
}
private void handleChoiceCallback(ChoiceCallback cc)
throws IOException
{
// not supported for server side
// ignore the provided defaultValue
/*
System.out.print(cc.getPrompt());
String [] strChoices = cc.getChoices();
for (int j = 0; j < strChoices.length; j++)
{
System.out.print("choice[" + j + "] : " + strChoices[j]);
}
System.out.flush();
cc.setSelectedIndex(Integer.parseInt((new BufferedReader
(new InputStreamReader(System.in))).readLine()));
*/
}
private void doLogin ()
{
// ... lots of other logic here
// TODO: Make this into modules with this one being for OpenAM
if (_useOpenAM)
{
String orgName = "/";
String moduleName = "DataStore";
String locale = "en_US";
AuthContext lc = new AuthContext(orgName);
AuthContext.IndexType indexType = AuthContext.IndexType.MODULE_INSTANCE;
lc.login(indexType, moduleName, locale);
boolean succeed = false;
Callback [] callbacks = null;
// get information requested from module
while (lc.hasMoreRequirements())
{
callbacks = lc.getRequirements();
if (callbacks != null)
{
addLoginCallbackMessage(loginBean, callbacks);
lc.submitRequirements(callbacks);
}
}
if (lc.getStatus() == AuthContext.Status.SUCCESS)
{
try
{
System.out.println("Login succeeded.");
openAMSessionId = lc.getAuthIdentifier();
System.out.println("lc.getAuthIdentifier()=" + openAMSessionId);
System.out.println("lc.getSuccessURL()=" + lc.getSuccessURL());
System.out.println("lc.getSSOToken().getAuthLevel()=" + lc.getSSOToken().getAuthLevel());
System.out.println("lc.getSSOToken().getAuthType()=" + lc.getSSOToken().getAuthType());
System.out.println("lc.getSSOToken().getHostName()=" + lc.getSSOToken().getHostName());
System.out.println("lc.getSSOToken().getIdleTime()=" + lc.getSSOToken().getIdleTime());
System.out.println("lc.getSSOToken().getMaxIdleTime()=" + lc.getSSOToken().getMaxIdleTime());
System.out.println("lc.getSSOToken().getMaxSessionTime()=" + lc.getSSOToken().getMaxSessionTime());
System.out.println("lc.getSSOToken().getTimeLeft()=" + lc.getSSOToken().getTimeLeft());
System.out.println("lc.getSSOToken().getIPAddress()=" + lc.getSSOToken().getIPAddress());
System.out.println("lc.getSSOToken().getTokenID()=" + lc.getSSOToken().getTokenID().toString());
System.out.println("lc.getSSOToken().getPrincipal()=" + lc.getSSOToken().getPrincipal().toString());
}
catch (Exception e)
{
e.printStackTrace();
}
succeed = true;
}
else if (lc.getStatus() == AuthContext.Status.FAILED)
{
System.out.println("Login failed.");
}
else
{
System.out.println("Unknown status: " + lc.getStatus());
}
System.out.println( "OpenAM login success=" + succeed);
}
}
The important thing from the above code is the variable openAMSessionId . That ends up having the new OpenAM single sign on session id that you can pass around to all of your protected client applications so that the user doesn't get challenged for login.
I hope this helps.
-dklotz