MOB-412: Decouple thread local authentication methods from AuthenticationComponent into new AuthenticationContext super-interface. The AuthenticationContext is a delegate of AbstractAuthenticationComponent and can be accessed directly by low-level classes (e.g. schema bootstrap) before the authentication subsystem is available.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13721 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2009-03-23 14:01:29 +00:00
parent 9cf5e4a004
commit aaea96e07c
2 changed files with 202 additions and 202 deletions

View File

@@ -85,7 +85,7 @@
<property name="tenantAdminService" ref="tenantAdminService"/> <property name="tenantAdminService" ref="tenantAdminService"/>
<property name="transactionService" ref="transactionComponent"/> <property name="transactionService" ref="transactionComponent"/>
<property name="authenticationComponent" ref="authenticationComponent"/> <property name="authenticationContext" ref="authenticationContext"/>
<property name="configDataCache" ref="globalConfigCache"/> <property name="configDataCache" ref="globalConfigCache"/>

View File

@@ -1,201 +1,201 @@
/* /*
* Copyright (C) 2005-2007 Alfresco Software Limited. * Copyright (C) 2005-2007 Alfresco Software Limited.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of * As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre * the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's * and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing * FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here: * the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" * http://www.alfresco.com/legal/licensing"
*/ */
package org.alfresco.web.app; package org.alfresco.web.app;
import java.util.Enumeration; import java.util.Enumeration;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; import javax.servlet.http.HttpSessionListener;
import javax.transaction.UserTransaction; import javax.transaction.UserTransaction;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.cache.InternalEhCacheManagerFactoryBean; import org.alfresco.repo.cache.InternalEhCacheManagerFactoryBean;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationContext;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.web.app.servlet.AuthenticationHelper; import org.alfresco.web.app.servlet.AuthenticationHelper;
import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.bean.repository.User; import org.alfresco.web.bean.repository.User;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.context.support.WebApplicationContextUtils;
/** /**
* ServletContextListener implementation that initialises the application. * ServletContextListener implementation that initialises the application.
* *
* NOTE: This class must appear after the Spring context loader listener * NOTE: This class must appear after the Spring context loader listener
* *
* @author gavinc * @author gavinc
*/ */
public class ContextListener implements ServletContextListener, HttpSessionListener public class ContextListener implements ServletContextListener, HttpSessionListener
{ {
private static Log logger = LogFactory.getLog(ContextListener.class); private static Log logger = LogFactory.getLog(ContextListener.class);
private ServletContext servletContext; private ServletContext servletContext;
/** /**
* @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
*/ */
public void contextInitialized(ServletContextEvent event) public void contextInitialized(ServletContextEvent event)
{ {
// make sure that the spaces store in the repository exists // make sure that the spaces store in the repository exists
this.servletContext = event.getServletContext(); this.servletContext = event.getServletContext();
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext); WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
// If no context has been initialised, exit silently so config changes can be made // If no context has been initialised, exit silently so config changes can be made
if (ctx == null) if (ctx == null)
{ {
return; return;
} }
ServiceRegistry registry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); ServiceRegistry registry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
TransactionService transactionService = registry.getTransactionService(); TransactionService transactionService = registry.getTransactionService();
NodeService nodeService = registry.getNodeService(); NodeService nodeService = registry.getNodeService();
SearchService searchService = registry.getSearchService(); SearchService searchService = registry.getSearchService();
NamespaceService namespaceService = registry.getNamespaceService(); NamespaceService namespaceService = registry.getNamespaceService();
AuthenticationComponent authenticationComponent = (AuthenticationComponent) ctx AuthenticationContext authenticationContext = (AuthenticationContext) ctx
.getBean("authenticationComponent"); .getBean("authenticationContext");
// repo bootstrap code for our client // repo bootstrap code for our client
UserTransaction tx = null; UserTransaction tx = null;
NodeRef companySpaceNodeRef = null; NodeRef companySpaceNodeRef = null;
try try
{ {
tx = transactionService.getUserTransaction(); tx = transactionService.getUserTransaction();
tx.begin(); tx.begin();
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); authenticationContext.setSystemUserAsCurrentUser();
// get and setup the initial store ref and root path from config // get and setup the initial store ref and root path from config
StoreRef storeRef = Repository.getStoreRef(servletContext); StoreRef storeRef = Repository.getStoreRef(servletContext);
// get root path // get root path
String rootPath = Application.getRootPath(servletContext); String rootPath = Application.getRootPath(servletContext);
// Extract company space id and store it in the Application object // Extract company space id and store it in the Application object
companySpaceNodeRef = Repository.getCompanyRoot(nodeService, searchService, namespaceService, storeRef, rootPath); companySpaceNodeRef = Repository.getCompanyRoot(nodeService, searchService, namespaceService, storeRef, rootPath);
Application.setCompanyRootId(companySpaceNodeRef.getId()); Application.setCompanyRootId(companySpaceNodeRef.getId());
// commit the transaction // commit the transaction
tx.commit(); tx.commit();
} }
catch (Throwable e) catch (Throwable e)
{ {
// rollback the transaction // rollback the transaction
try try
{ {
if (tx != null) if (tx != null)
{ {
tx.rollback(); tx.rollback();
} }
} }
catch (Exception ex) {} catch (Exception ex) {}
logger.error("Failed to initialise ", e); logger.error("Failed to initialise ", e);
throw new AlfrescoRuntimeException("Failed to initialise ", e); throw new AlfrescoRuntimeException("Failed to initialise ", e);
} }
finally finally
{ {
try try
{ {
authenticationComponent.clearCurrentSecurityContext(); authenticationContext.clearCurrentSecurityContext();
} }
catch (Exception ex) {} catch (Exception ex) {}
} }
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
* <p> * <p>
* Forcibly kills Alfresco's EHCache CacheManager * Forcibly kills Alfresco's EHCache CacheManager
*/ */
public void contextDestroyed(ServletContextEvent event) public void contextDestroyed(ServletContextEvent event)
{ {
InternalEhCacheManagerFactoryBean.getInstance().shutdown(); InternalEhCacheManagerFactoryBean.getInstance().shutdown();
} }
/** /**
* Session created listener * Session created listener
*/ */
public void sessionCreated(HttpSessionEvent event) public void sessionCreated(HttpSessionEvent event)
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("HTTP session created: " + event.getSession().getId()); logger.debug("HTTP session created: " + event.getSession().getId());
} }
/** /**
* Session destroyed listener * Session destroyed listener
*/ */
public void sessionDestroyed(HttpSessionEvent event) public void sessionDestroyed(HttpSessionEvent event)
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("HTTP session destroyed: " + event.getSession().getId()); logger.debug("HTTP session destroyed: " + event.getSession().getId());
String userKey = null; String userKey = null;
if (Application.inPortalServer() == false) if (Application.inPortalServer() == false)
{ {
userKey = AuthenticationHelper.AUTHENTICATION_USER; userKey = AuthenticationHelper.AUTHENTICATION_USER;
} }
else else
{ {
// search for the user object in the portlet wrapped session keys // search for the user object in the portlet wrapped session keys
// each vendor uses a different naming scheme so we search by hand // each vendor uses a different naming scheme so we search by hand
String userKeyPostfix = "?" + AuthenticationHelper.AUTHENTICATION_USER; String userKeyPostfix = "?" + AuthenticationHelper.AUTHENTICATION_USER;
Enumeration enumNames = event.getSession().getAttributeNames(); Enumeration enumNames = event.getSession().getAttributeNames();
while (enumNames.hasMoreElements()) while (enumNames.hasMoreElements())
{ {
String name = (String)enumNames.nextElement(); String name = (String)enumNames.nextElement();
if (name.endsWith(userKeyPostfix)) if (name.endsWith(userKeyPostfix))
{ {
userKey = name; userKey = name;
break; break;
} }
} }
} }
if (userKey != null) if (userKey != null)
{ {
User user = (User)event.getSession().getAttribute(userKey); User user = (User)event.getSession().getAttribute(userKey);
if (user != null) if (user != null)
{ {
// invalidate ticket and clear the Security context for this thread // invalidate ticket and clear the Security context for this thread
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
AuthenticationService authService = (AuthenticationService)ctx.getBean("authenticationService"); AuthenticationService authService = (AuthenticationService)ctx.getBean("authenticationService");
authService.invalidateTicket(user.getTicket()); authService.invalidateTicket(user.getTicket());
authService.clearCurrentSecurityContext(); authService.clearCurrentSecurityContext();
event.getSession().removeAttribute(userKey); event.getSession().removeAttribute(userKey);
} }
} }
} }
} }