Single Sign On (SSO) in JBoss / Tomcat / JBoss Portal
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-25-2006 12:49 PM
Alfresco gurus:
I'm trying to implement single sign on between JBoss Portal and Alfresco running as a portlet in the same tomcat servlet container (no cluster). I have Tomcat's SingleSignOn value operational and single sign on works between web applications that use container based authentication just fine. I have tried a few hacks to try and propagate the JBoss Portal authenticated user credentials to the Alfresco portlet, but I feel like I'm back to square one.
Can anyone be of service here? I have a good understanding of container based authentication, but only a moderate understanding of Acegi (but I'm reading more right now!).
Environment:
JBoss Portal 1.2.1
Alfresco 1.3 community
Any help would be greatly appreciated!
I'm trying to implement single sign on between JBoss Portal and Alfresco running as a portlet in the same tomcat servlet container (no cluster). I have Tomcat's SingleSignOn value operational and single sign on works between web applications that use container based authentication just fine. I have tried a few hacks to try and propagate the JBoss Portal authenticated user credentials to the Alfresco portlet, but I feel like I'm back to square one.
Can anyone be of service here? I have a good understanding of container based authentication, but only a moderate understanding of Acegi (but I'm reading more right now!).
Environment:
JBoss Portal 1.2.1
Alfresco 1.3 community
Any help would be greatly appreciated!
Labels:
- Labels:
-
Archive
14 REPLIES 14
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-15-2006 11:08 AM
Just to keep this thread going, I've made some modifications to the AuthenticationPortletFilter.java to address user logout and a Alfresco configuration parameter.
[1] Logout: I was having trouble with session expiration in Alfresco when someone would log in to JBP as user 1, go to the Alfresco portlet, logout of JBP, log in to JBP as user 2, and go the Alfresco portlet. In this case, the Alfresco portlet would still maintain their session as user 1. To fix this, I added some code to the PortletFilter to make sure the JOSSO session associated with their username is still valid.
[2] Alfresco configuration: Now the PortletFilter takes an initiation parameter to dynamically configure whether or not Alfresco thinks external authentication is occuring. This parameter controls whether or not Alfresco allows an administrative user to create new users (and maybe group associations?).
AuthenticationPortletFilter:
The configuration in portlet.xml:
[1] Logout: I was having trouble with session expiration in Alfresco when someone would log in to JBP as user 1, go to the Alfresco portlet, logout of JBP, log in to JBP as user 2, and go the Alfresco portlet. In this case, the Alfresco portlet would still maintain their session as user 1. To fix this, I added some code to the PortletFilter to make sure the JOSSO session associated with their username is still valid.
[2] Alfresco configuration: Now the PortletFilter takes an initiation parameter to dynamically configure whether or not Alfresco thinks external authentication is occuring. This parameter controls whether or not Alfresco allows an administrative user to create new users (and maybe group associations?).
AuthenticationPortletFilter:
package gov.doi.usgs.alfresco.security;import java.io.IOException;import java.util.Map;import javax.faces.context.FacesContext;import javax.portlet.ActionRequest;import javax.portlet.ActionResponse;import javax.portlet.PortletException;import javax.portlet.RenderRequest;import javax.portlet.RenderResponse;import javax.portlet.PortletRequest;import javax.portlet.PortletSession;import javax.servlet.http.Cookie;import javax.transaction.UserTransaction;import org.apache.portals.bridges.portletfilter.PortletFilter;import org.apache.portals.bridges.portletfilter.PortletFilterChain;import org.apache.portals.bridges.portletfilter.PortletFilterConfig;import org.apache.commons.lang.StringUtils;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.web.context.WebApplicationContext;import org.alfresco.model.ContentModel;import org.alfresco.repo.security.authentication.AuthenticationComponent;import org.alfresco.service.ServiceRegistry;import org.alfresco.service.cmr.repository.NodeService;import org.alfresco.service.cmr.repository.NodeRef;import org.alfresco.service.cmr.security.AuthenticationService;import org.alfresco.service.cmr.security.PersonService;import org.alfresco.service.transaction.TransactionService;import org.alfresco.web.app.servlet.AuthenticationHelper;import org.alfresco.web.bean.LoginBean;import org.alfresco.web.bean.repository.User;import org.josso.Lookup;import org.josso.gateway.Constants;import org.josso.gateway.session.SSOSession;import org.josso.gateway.session.service.SSOSessionManager;/** * Filters every request for the Alfresco portlet and makes sure that the correct * user PortletSession environment exists so that the user is not asked to re-authenticate * * <h5>Initialization Parameters</h5> * * <b>alfrescoExternalAuth</b>: true/false [default true]. Configures Alfresco to use * external authentication or not. If true, certain user controls are not available in Alfresco * * @author Jon French */ public class AuthenticationPortletFilter implements PortletFilter { private static final Log LOG = LogFactory.getLog(AuthenticationPortletFilter.class); private AuthenticationService fAuthService; private AuthenticationComponent fAuthComponent; private PersonService fPersonService; private NodeService fNodeService; private TransactionService fTransactionService; private Boolean fAlfrescoExternalAuthentication = Boolean.TRUE; public void init(PortletFilterConfig filterConfig) throws PortletException{ WebApplicationContext ctx = (WebApplicationContext)filterConfig.getPortletConfig().getPortletContext().getAttribute( WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); fNodeService = serviceRegistry.getNodeService(); fTransactionService = serviceRegistry.getTransactionService(); fAuthService = (AuthenticationService) ctx.getBean("authenticationService"); fAuthComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent"); fPersonService = (PersonService) ctx.getBean("personService"); String alfrescoExternalAuth = filterConfig.getInitParameter("alfrescoExternalAuth"); if (alfrescoExternalAuth != null) { fAlfrescoExternalAuthentication = Boolean.valueOf(alfrescoExternalAuth); if (LOG.isDebugEnabled()) { LOG.debug("Alfresco is configured to external authentication: " + fAlfrescoExternalAuthentication); } } if (LOG.isDebugEnabled()) { LOG.debug(getClass().getName() + " initialized"); } } public void renderFilter(RenderRequest request, RenderResponse response, PortletFilterChain chain) throws PortletException, IOException{ if (LOG.isDebugEnabled()) { LOG.debug("here in renderFilter"); } ensureLogin(request); chain.renderFilter(request,response); } public void processActionFilter(ActionRequest request, ActionResponse response, PortletFilterChain chain) throws PortletException, IOException{ if (LOG.isDebugEnabled()) { LOG.debug("here in renderFilter."); } ensureLogin(request); chain.processActionFilter(request,response); } public void destroy(){ } private void ensureLogin(PortletRequest request) throws PortletException,IOException { PortletSession session = request.getPortletSession(); User user = (User) session.getAttribute(AuthenticationHelper.AUTHENTICATION_USER); String ssosessionId = retreiveSSOId(request); if (ssosessionId == null) { /* If the a SSO session id is not stored as a cookie, something is wrong since the user should always have to go through JOSSO to get to this filter. */ throw new PortletException("SSO session cookie is not present"); } SSOSession ssoSession = retrieveSSOSession(ssosessionId); /* Case 1: The Alfresco user is NOT null, but the SSOSession is null or not valid. In this case, something happened (the user logged out, the SSOSession timed out) which ended the SSOSession. Case 2: The user name associated with the Alfresco session and SSOSession are NOT the same. This can happen if the user logs out and logs in as a different user. In either case, I need to end the Alfresco user session. I copied the code to end the Alfresco user's sesseion from the org.alfresco.web.bean.LoginBean.logout() method from Alfresco community 1.3 */ if (LOG.isDebugEnabled()) { LOG.debug("Determining if alfresco user is valid. \n" + "((ssoSession == null || !ssoSession.isValid()) && user != null): " + ((ssoSession == null || !ssoSession.isValid()) && user != null) + "\n" + "(ssoSession != null && user != null && !user.getUserName().equals(ssoSession.getUsername())): " + (ssoSession != null && user != null && !user.getUserName().equals(ssoSession.getUsername())) ); } if (((ssoSession == null || !ssoSession.isValid()) && user != null) || // case 1 (ssoSession != null && user != null && !user.getUserName().equals(ssoSession.getUsername()))) // case 2 { LOG.debug("Disabling alfresco user."); // invalidate ticket and clear the Security context for this thread fAuthService.invalidateTicket(user.getTicket()); fAuthService.clearCurrentSecurityContext(); // remove all objects from our session by hand // we do this as invalidating the Portal session would invalidate all other portlets! if (FacesContext.getCurrentInstance() != null && FacesContext.getCurrentInstance().getExternalContext() != null ) { Map sesMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap(); for (Object key : sesMap.keySet()) { sesMap.remove(key); } } // Set the user equal to null user = null; } if (user == null) { if (LOG.isDebugEnabled()) { LOG.debug("session user attribute is null."); } if (ssoSession == null || !ssoSession.isValid()) { throw new PortletException("SSO Session not valid"); } /* Make sure the user is loaded into the PortletSession environment. The code below is modeled on the Alfresco org.alfresco.web.app.servlet.NTLMAuthenticationFilter */ UserTransaction tx = fTransactionService.getUserTransaction(); NodeRef homeSpaceRef = null; try { tx.begin(); // Get user details for the authenticated user fAuthComponent.setCurrentUser(ssoSession.getUsername().toLowerCase()); // The user name used may be a different case to the NTLM supplied user name, read the current // user and use that name String userName = fAuthComponent.getCurrentUserName(); // Setup User object and Home space ID etc. NodeRef personNodeRef = fPersonService.getPerson(userName); String currentTicket = fAuthService.getCurrentTicket(); user = new User(userName, currentTicket, personNodeRef); homeSpaceRef = (NodeRef) fNodeService.getProperty( personNodeRef, ContentModel.PROP_HOMEFOLDER); user.setHomeSpaceId(homeSpaceRef.getId()); tx.commit(); } catch (Throwable ex) { try { tx.rollback(); } catch (Exception ex2) { LOG.error("Failed to rollback transaction", ex2); } if(ex instanceof RuntimeException) { throw (RuntimeException)ex; } else if(ex instanceof IOException) { throw (IOException)ex; } else if(ex instanceof PortletException) { throw (PortletException)ex; } else { throw new RuntimeException("Authentication setup failed", ex); } } // Store the user session.setAttribute(AuthenticationHelper.AUTHENTICATION_USER, user); /* This parameter tells Alfresco if you are using external authentication. If true, one thing it will do is remove the "create user" button Note that there seems to be a bug in Alfresco in that Alfresco only checks for the presence/absence of the the LoginBean.LOGIN_EXTERNAL_AUTH session attribute instead of its value. This means that the attribute can equal Boolean.FALSE but NOT display the "Create user" button. */ if (Boolean.TRUE.equals(fAlfrescoExternalAuthentication)) { session.setAttribute(LoginBean.LOGIN_EXTERNAL_AUTH,Boolean.TRUE); } // Note! If you wanted to do any fancy Locale stuff, you should do it here. if ( LOG.isDebugEnabled()){ LOG.debug("User logged on via JOSSO"); } return; } else{ if (LOG.isDebugEnabled()) { LOG.debug("session user attribute is NOT null: \n\n" + "username: " + user.getUserName() + "\n"); } } } /** * Retreives the JOSSO single sign on cookie from the PortletRequest */ private String retreiveSSOId(PortletRequest request){ String ssosessionId = null; String cookies1 = request.getProperty("cookie"); String[] cookies2 = StringUtils.split(cookies1,";"); if (cookies2 != null) { for (int i = 0;i<cookies2.length;i++) { String[] c = StringUtils.split(cookies2[i],"="); if (Constants.JOSSO_SINGLE_SIGN_ON_COOKIE.equals(c[0].trim())) { ssosessionId = c[1]; break; } } } if (LOG.isDebugEnabled()) { LOG.debug("SSO cookie found. value: " + ssosessionId); } return ssosessionId; } /** * Retreive the JOSSO session from JOSSO. */ private SSOSession retrieveSSOSession(String ssosessionId) throws PortletException{ try{ SSOSessionManager manager = Lookup.getInstance().lookupSecurityDomain().getSessionManager(); return manager.getSession(ssosessionId); }catch(Exception e){ throw new PortletException("Problem obtaining SSOSession",e); } }}
The configuration in portlet.xml:
<portlet id="FilteredAlfresco"> <portlet-name>FilteredAlfresco</portlet-name> <display-name>Document management</display-name> <portlet-class>org.apache.portals.bridges.portletfilter.FilterPortlet</portlet-class> <init-param> <name>portlet-class</name> <value>org.alfresco.web.app.portlet.AlfrescoFacesPortlet</value> </init-param> <!– Important! The default view is where the MyFacesPortlet will take the user in absence of any species view id in the users session. This should be the browse page, not the login page –> <init-param> <name>default-view</name> <value>/jsp/browse/browse.jsp</value> </init-param> <init-param> <name>portlet-filters</name> <value>gov.doi.usgs.alfresco.security.AuthenticationPortletFilter</value> </init-param> <init-param> <name>gov.doi.usgs.alfresco.security.AuthenticationPortletFilter:alfrescoExternalAuth</name> <value>false</value> </init-param> <expiration-cache>0</expiration-cache> <supports> <mime-type>text/html</mime-type> <portlet-mode>VIEW</portlet-mode> </supports> <supported-locale>en</supported-locale> <supported-locale>ja</supported-locale> <portlet-info> <title>Filtered Alfresco</title> <short-title>This is a filtered portlet for alfresco</short-title> </portlet-info> </portlet></portlet-app>
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-21-2007 11:00 AM
Hello, I want to do the same thing with a Liferay Portal. So can anyone help us ?
Thank you.
We (http://www.tejasoft.com) has done liferay and josso integration. More details could be found at http://www.liferay.com/web/guest/devzone/forums/message_boards/message/18481
Regards,
Nagendra
C.T.O
http://www.tejasoft.com

Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-04-2007 02:03 PM
I have the same problem and your solution sounds really great. When I tried to implement it a similar way, I found the following problem.
In your class gov.doi.usgs.josso.JBossPortalIdentityStore you use
These classes aren't present in JBoss-Portal since version 2.4 - as far as I've seen. First I thought they simply moved to package org.jboss.portal.identity, but the interface User found there has no method getRoles().
Do you - or anybody else - know what happened there?
Regards,
Hajo
In your class gov.doi.usgs.josso.JBossPortalIdentityStore you use
import org.jboss.portal.core.modules.UserModule;import org.jboss.portal.core.model.User;
These classes aren't present in JBoss-Portal since version 2.4 - as far as I've seen. First I thought they simply moved to package org.jboss.portal.identity, but the interface User found there has no method getRoles().
Do you - or anybody else - know what happened there?
Regards,
Hajo

Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-08-2007 07:00 AM
If you want sign on with jb portal and you don't need SSO or you want to modify this so it work on JB Portal 2.6 please refer to
http://forums.alfresco.com/viewtopic.php?p=28282
Many thanks to jfrench for this example, I based on.
Cheers,
Tomek
http://forums.alfresco.com/viewtopic.php?p=28282
Many thanks to jfrench for this example, I based on.
Cheers,
Tomek
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-29-2010 04:15 AM
Idont know what happen to my AWPr .I am trying to implement AWPr on JBoss Portal ,Every thing goes fine but when portal is displayed only the header is shown no file list display some error shows in FireFox error console.
How can i slove that problem ,
Thanks in advance
How can i slove that problem ,
Thanks in advance
