mardi 8 avril 2008

OpenSSO Information Card Extensions Demo at Concordia Workshop RSA 2008

Pat Patterson announced yesterday that the RSA IOP scenario, held Monday, April 7, 2008, featured the Information Card RP and IdP/STS extensions of OpenSSO. Notes from the Concordia workshop still to be supplied. I believe Pat did some enhancements to the Information Card RP authentication module to support the declaration of dynamic claims passed directly in the request URI. More on this latter... Further I3 user-centric identity interoperability demonstrations will be held Tuesday, April 8 and Wednesday, April 9, 2008 at the Moscone Center. So, Pat, we are counting on you to let us known how things worked out.

lundi 7 avril 2008

Writing a Relying Party for the OpenSSO Information Card Authentication Module

This post explains how to write a simple relying party web application using the Information Card Authentication Module extension of OpenSSO. This is two simple steps detailed below:
  1. Install and setup the Information Card Authentication Module following the instructions outlined in the README file.
  2. Create a web application that will use the Client SDK for Java.
Once you have created your web application project, using Netbeans for instance, you need to add the Client SDK for Java in the project's libraries property. If you installed OpenSSO, the jar file is located under install-dir/libraries/jar/openssoclientsdk.jar

Then, you'll need to prepare the AMConfig.properties file which contains parameters used by the SDK to connect to the OpenSSO services. You can do it either manually (the hard way), or deploy the samples web application provided in
install-dir/samples/war/fam-client-jdk15.war. First, unzip fam-client.zip and then deploy the WAR file. This web application invokes a JSP (i.e. Configurator.jsp), which creates a AMConfig.properties file in the user's home directory. Personally, I used the defaults for user name and password (i.e. anonymous) which happened to work fine for my needs. This part is little a tricky but not unsurmountable.
This unfortunate convolution comes from the lack of an installer and specific documentation, that are included with Access Manager, but not with the open source project.


You can verify that the AMConfig.properties is properly configured by playing with the samples web application. Once you get there, writing and deploying a relying party web application using the Information Card authentication module is fairly easy. Here is an example that I provided for your convenience. Create a servlet in your project and copy the file below. It should work...


package com.identarian.infocard.opensso.ssosample;

import com.iplanet.am.util.SystemProperties;
import com.iplanet.sso.SSOException;
import com.iplanet.sso.SSOToken;
import com.iplanet.sso.SSOTokenListener;
import com.iplanet.sso.SSOTokenManager;
import com.sun.identity.idm.AMIdentity;
import com.sun.identity.idm.IdRepoException;
import com.sun.identity.idm.IdUtils;
import java.io.*;
import java.net.*;

import java.util.Map;
import java.util.Properties;
import javax.servlet.*;
import javax.servlet.http.*;

/**
*
* @author ppetit
*/
public class SSOTokenSample extends HttpServlet {

private static boolean initialized = false;
private static String host = null;
private static String port = null;
private static String proto = null;
ServletOutputStream out = null;

@Override
public void init() {

String configFile = System.getProperty("user.home")
File.separator "AMConfig.properties";
Properties props = new Properties();
try {
props.load(new FileInputStream(configFile));
} catch (IOException e) {
System.out.println("Failed to load AMConfig.properties");
return;
}

host = props.getProperty("com.iplanet.am.server.host", "localhost");
port = props.getProperty("com.iplanet.am.server.port", "8181");
proto = props.getProperty("com.iplanet.am.server.protocol", "https");

SystemProperties.initializeProperties(props);


initialized = true;
}

/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
*/
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

response.setContentType("text/html;charset=UTF-8");

try {
out = response.getOutputStream();

// create the sso token from http request
SSOTokenManager manager = SSOTokenManager.getInstance();
SSOToken token = manager.createSSOToken(request);
out.println("Entering SSOTokenSample.java");
out.println("<br />");
// throws an exception if token is not valide
manager.validateToken(token);
//print some of the values from the token.

java.security.Principal principal = token.getPrincipal();
String authType = token.getAuthType();

out.println("SSOToken Principal name: "
principal.getName());
out.println("<br />");
out.println("Authentication type used: " authType);
out.println("<br />");

// Retrieve user profile and print them
AMIdentity userIdentity = IdUtils.getIdentity(token);
Map attrs = userIdentity.getAttributes();
out.println("User Attributes: " attrs);
out.println("<br />");
// Retreive user session properties
out.println("Session properties:");
String ppid = token.getProperty("privatepersonalidentifier");
if (ppid != null && ppid.length() != 0) {
out.println("PPID: " ppid);
}
String gname = token.getProperty("givenname");
String sname = token.getProperty("surname");
if (gname != null && sname != null) {
out.println("Welcome " gname " " sname);
}
out.println("<br />");
/*
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname">
<PARAM Name="optionalClaims" Value="
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/streetaddress
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/locality
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/stateorprovince
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/homephone
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/otherphone
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobilephone
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/gender

http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
*/
/* let us add a listener to the SSOToken. Whenever a token
* event arrives, ssoTokenChanged method of the listener will
* get called.
*/
SSOTokenListener myListener = new SampleTokenListener();
token.addSSOTokenListener(myListener);
} catch (SSOException e) {
// No valid SSO token in request redirect to Infocard authh module
String openssoUrl = proto "://" host ":" port
"/opensso/UI/Login?module=Infocard&goto="
request.getRequestURL().toString();
response.sendRedirect(openssoUrl);
} catch (IdRepoException e) {
out.println("IdRepo Exception: " e);
e.printStackTrace();
} catch (IOException e) {
out.println("IO Exception: " e);
e.printStackTrace();
} finally {
out.flush();
}

}

/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
*/
@Override
public String getServletInfo() {
return "SSOTokenSample servlet demonstrate the use of OpenSSO client SDK";
}
// </editor-fold>
}


[1] Client SDK configuration properties loaded from AMConfig.properties
[2] Initialize the SDK with properties
[3] Test whether a valid token is present in the request or not
[4] Display user's identity repository data, that is only the uid / password in the case
of Information Card authentication module
[5] Display Information Card claims stored in the session by the module
[6] An SSOException is thrown because the token is invalid. The catch block sends a redirect to the Information Card auth module, which in turn, sends the user back (notice the goto) to the RP's current URL when the authentication is complete

vendredi 4 avril 2008

Information Card Authentication Module with OpenSSO Build 4

I upgraded to OpenSSO Build 4 this morning to test the Information Card Relying Party authentication module (i.e. authnicrp OpenSSO extension). I did some changes that I committed to the opensso/extension build yesterday. The changes improve the configurability and security of the module, thanks to Axel's explanation about the use of the Token.getClientDigest() method of the xmldap.org library. Also, notice that you will have to recompile xmldap-1.0.jar with the latest of xmldap.org build to get a fix for this method and run the Information Card authentication module.

jeudi 3 avril 2008

OpenSSO Build 4 is out-of-the-door

OpenSSO build 4 availability was announced earlier this week on The Aquarium with a support for WS-Trust based Security Token Service (STS) (based on Metro).