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

5 commentaires:

emily a dit…

this kind of blog always useful for blog readers, it helps people during research. your post is one of the same for blog readers.

Thesis Papers

Dissertation Help a dit…

Wonderful post, thanks for putting this together! "This is obviously one great post about "Writing a Relying Party for the OpenSSO Information Card Authentication Module". Dissertation Help | Custom Dissertation

Carlos a dit…

Hi there,
How can I import com.iplanet.sso
In Netbeans he doesn´t knows it..

Thanks

Patrick Petit a dit…

Of course NetBeans doesn't know that library. You need to download the client sdk and install the library under NetBeans.

doglas markel a dit…

we area unit throughout this text which can assist you beside your short economic desires. the actual day advance may well be a pleasant product or service that will permits associate degree outsized vary of people, like you, day-to-day! Whenever emergencies happen, don’t anxiety! Arrive see u. s. of America all. we have a tendency cash advance
to tend to stand live generally there for you head to head and in addition we have a tendency to tend to calculate aiding you beside your economic desires.