Liferay and WebSphere SSO (simplistic)

Posted by eichelgartenweg on 3:10 PM with 2 comments
Since Liferay is providing CAS (Central Authentication Service) support its possible to access Liferay through WebSphere SSO (LTPA tokens) login credentials.
So what to do?
I can not post all of our source code because of "some security" issues :-)
Steps:
1. Edit portel-ext.properties (or portal-impl.jar//portal.properties)
1.1 Add/Edit the CAS configuration lines
##
## CAS
##
cas.auth.enabled=true
#
cas.import.from.ldap=false
#
cas.login.url=/portal/cas-web/login
cas.logout.url=/portal/html/common/was_logout.jsp
cas.service.url=/portal/c/portal/login
cas.validate.url=/portal/cas-web/proxyValidate

The bold lines say Liferay where to login or logout

2. Create Java-Classes for decrypting the WebSphere LTPA-Token
Have a look at these examples
http://blog.offbytwo.com/2007/08/21/working-with-lightweight-third-party-authentication-ltpa/
http://offbytwo.googlecode.com/svn/trunk/bitsandpieces/LTPAUtils/

and copy them to WEB-INF/classes/<class path> (or pack them into a jar-file)

3. Add AutoLogin-Classes (Step 2) to portal-ext.properties
auto.login.hooks=<class to decrypt ltpa token>,com.liferay.portal.security.auth.CASAutoLogin,...

4. Add was_logout.jsp to specify the cas-logout-path (see step 1)
Content (example):
<div style="text-align: center; color: rgb(153, 153, 153);"><%@ page import="java.util.*" %>
<%@ page import="com.liferay.portal.util.*;" %>
<title></title>
<form method="post" action="ibm_security_logout" name="logout">
<input name="logout" value="Logout" type="submit">
<input name="logoutExitPage" value="/" type="hidden">
</form>
<%-- auto-submitted by javascript --%>
<script type="text/javascript"><!-- logout.submit(); // --></script>

</div>

5. Create new Sign in portlet or edit the delivered sign in portlet
Content of view.jsp (example):
<% if (!themeDisplay.isSignedIn()) { %>

<%-- /* <form action="<portlet:renderURL windowState=">"><portlet:param name="struts_action" value="/mnet_sso_login/sso_forward"></portlet:param>" method="post" name="<portlet:namespace>fm"> */ --%>
fm">

<table class="login-table">

<tbody><tr>
<td style="padding-bottom: 10px;">
<liferay-ui:message key="login">
</liferay-ui:message></td>
<td>
<input name="j_username" class="form_input" type="text">
</td>
</tr>
<tr>
<td style="padding-bottom: 10px;">
<liferay-ui:message key="password">
</liferay-ui:message></td>
<td>
<input name="j_password" class="form_input" type="password">

</td>
</tr>
<tr>
<td>
</td>
<td>
<input class="form_button" name="" type="submit">submit" value="<liferay-ui:message key="sign-in">">
</liferay-ui:message></td>
</tr>

</tbody></table>

</portlet:namespace>
<% } %>

6. Add Login-config to web.xml
...
<login-config>
<auth-method>FORM</auth-method>
<realm-name>PortalRealm</realm-name>
<form-login-config>
<form-login-page>/c/portal/j_login</form-login-page>
<form-error-page>/portal/web/guest/login/error</form-error-page>
</form-login-config>
</login-config>
...


Thats it

Workflow:
User logs in > LTPA-Token cookie is created by WebSphere >
Custom AutoLogin-Class is called > Custom AutoLogin-Class reads Cookies > Custom AutoLogin-Class decrypts LTAP-Token from Cookie > Custom AutoLogin-Class returns credentials array
Example:
credentials[0] = String.valueOf(user.getUserId());
credentials[1] = user.getPassword();
credentials[2] = boolean.TRUE.toString();
> Liferay accepts login