Setting a cookie for the user logged in
Wouldn't it be nice if your Portal provided some mechanism to lookup who is logged in? Perhaps a domain wide cookie that other application could read? At Clayton State, we have done just that using the iPerson object. Our external channels can read this cookie, verify its contents, and set the user to deliver truly personalized content.
The iPerson object
The iPerson object is a class in Java that we can query to find out information about who is logged into the Portal. Look at the following code:
<%@ page language="java" contentType="text/html" %>
<%@ page import="java.util.*" %>
<%@ page import="org.jasig.portal.security.provider.*" %>
<%@ page import="org.jasig.portal.security.*" %>
<%@ page import="javax.servlet.http.HttpServletRequest" %>
<%!
private String getIPersonAttribute(HttpServletRequest hsr, String attr)
throws PortalSecurityException
{
StringBuffer sb = new StringBuffer();
SimplePersonManager spm = new SimplePersonManager();
IPerson i = spm.getPerson(hsr);
sb.append( (String)i.getAttribute(attr));
return sb.toString();
}
%>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>SWAN Utility</title>
<script type="text/javascript">
window.onload = function() {
document.cookie = "swan=" + escape("<%= getIPersonAttribute(request, "username") %>") + ":" + escape("<%= getIPersonAttribute(request, "urn:sungardhe:dir:loginId") %>") + ":" + "encryption_key_to_verify_authenticity" + ";domain=.clayton.edu";
}
</script>
</head>
</html>
Lets walk through the code:
- The first part loads a bunch of name spaces that Java needs - including the org.jasig.portal.security.*
- The next part defines a function that queries thats in an attribute, and returns the value for that attribute
- Below, we write our HTML to set a domain cookie with the following attributes: uid, username, and encryption key
- The domain-scope of this cookie a site wide cookie. Anything matching a DNS ending of ".clayton.edu" can read this cookie
Everything is pretty standard, except for the encryption string. This should be some algorithm that you invent and push from the server side to keep people from just altering their cookie and stealing another user's session. It should probably change every day using by including a timestamp, and be specific to the user account so everyone doesn't have the same key. Don't implement your solution in Javascript, otherwise your algorithm will be in clear-text in the source code!
Special thanks to the folks at Lumdev.net that have posted various articles on the iPerson object - otherwise it would have not been possible!
Now what?
If you place this jsp file inside of a hidden iFrame, or make the login page hit this URL on login, it will automatically set the cookie for each user.
From this point on, you can verify the user, and use this information in a myriad of different ways, including channel development.

Suggestions
Not a bad idea. Here are a few suggestions...
1) Use a one-way hashing algorithm for the encryption method. SHA-1 seems to be a good. Avoid MD5 since a collision attack is becoming easier.
2) Hash all the fields passed, plus a timestamp, plus a secret key you choose. Pass all the parameters (except the secret key) along with the hash result.
3) On the external authentication page, verify the authenticity of the message and that is has not been tampered with by hashing the passed parameters (minus the hash) along with the same secret key. Compare the calculated hash result to the passed hash result. If they match, then the data has not been altered.
4) To prevent people from being able to look in the cache or history, brute forcing the login, or bookmarking the login, compare the passed timestamp to the time of the server. If it matches within a small interval, then you are okay to go. If not, then it's probably an old login attempt that shouldn't be valid anymore, so reject it.
Capture login
Hey Ben,
A similar, server-based method that we have been using for sometime is to use standard Servlet Forwarding to capture the Luminis login, do something with it(in our case, create a domain wide cookie of our own baking) and then servlet forward to the Luminis login process. Works great.
See: http://www.lumdev.net/comment/reply/301
and 'capture luminis login' at: http://coho.langara.bc.ca/luminis/fixes/
Bob.