From 634fb92904910f780774a6010858f50e9c81b474 Mon Sep 17 00:00:00 2001 From: Dave Ward Date: Tue, 18 Aug 2009 17:45:05 +0000 Subject: [PATCH] Merged V3.2 to HEAD 15602: Merged V3.1 to V3.2 13861: Web Script 'Index' pages now require admin access 13868: Fix org.alfresco.error.AlfrescoRuntimeException: Read-Write transaction started within read-only transaction 13873: MT - fix ETHREEOH-1735 (web scripts re-directed to a different tenant's noderef - HTTP 500) 13905: MT - fix ETHREEOH-1735 (follow-on ... fix the !) 15798: ETHREEOH-2686: Resolved problem with site dashboards disappearing after NTLM login / session expiry - RemoteStore.hasDocument() throws IOException rather than returning false if a non HTTP 200 response is received from the remoteavm web ScriptContent - This prevents us from incorrectly caching the non-existence of certain pages - remoteavm webscript authentication changed back to "none" so that the share NTLMAuthenticationFilter can pre-fetch pages to determine their required authentication level - Multi-tenancy implications resolved by making "guest" the minimum required authentication for scripts in the Repository Webscript Container when MT is enabled git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@15800 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../repository/store/remoteavm.get.desc.xml | 2 +- .../web-scripts-application-context.xml | 8 +- .../repo/web/scripts/RepositoryContainer.java | 90 +++++++++++++++++-- 3 files changed, 91 insertions(+), 9 deletions(-) diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/remoteavm.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/remoteavm.get.desc.xml index 0ff8314839..b204c63daf 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/remoteavm.get.desc.xml +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/remoteavm.get.desc.xml @@ -7,7 +7,7 @@ /remotestore/{method}/s/{store}/{path} /remotestore/{method}/s/{store}/w/{webapp} /remotestore/{method}/s/{store}/w/{webapp}/{path} - guest + none required argument \ No newline at end of file diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index dd1abddf43..2966ff5f00 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -1,5 +1,5 @@ - + @@ -143,7 +143,11 @@ - + + + + + diff --git a/source/java/org/alfresco/repo/web/scripts/RepositoryContainer.java b/source/java/org/alfresco/repo/web/scripts/RepositoryContainer.java index 542bf519b7..bca255a7ac 100644 --- a/source/java/org/alfresco/repo/web/scripts/RepositoryContainer.java +++ b/source/java/org/alfresco/repo/web/scripts/RepositoryContainer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2008 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -70,6 +70,9 @@ import org.alfresco.web.scripts.Description.TransactionCapability; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.ObjectFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.event.ContextRefreshedEvent; /** @@ -239,17 +242,22 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten { WebScript script = scriptReq.getServiceMatch().getWebScript(); Description desc = script.getDescription(); + + // Escalate the webscript declared level of authentication to the container required authentication (must be + // guest if MT is enabled) RequiredAuthentication required = desc.getRequiredAuthentication(); + RequiredAuthentication containerRequiredAuthentication = getRequiredAuthentication(); + if (required.compareTo(containerRequiredAuthentication) < 0) + { + required = containerRequiredAuthentication; + } boolean isGuest = scriptReq.isGuest(); if (required == RequiredAuthentication.none) { - // MT-context will pre-authenticate (see MTWebScriptAuthenticationFilter) - if (! AuthenticationUtil.isMtEnabled()) - { // TODO revisit - cleared here, in-lieu of WebClient clear - AuthenticationUtil.clearCurrentSecurityContext(); - } + AuthenticationUtil.clearCurrentSecurityContext(); + transactionedExecuteAs(script, scriptReq, scriptRes); } else if ((required == RequiredAuthentication.user || required == RequiredAuthentication.admin) && isGuest) @@ -284,6 +292,12 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script " + desc.getId() + " requires admin authentication; however, a non-admin has attempted access."); } + if (logger.isDebugEnabled()) + { + currentUser = AuthenticationUtil.getFullyAuthenticatedUser(); + logger.debug("Authentication: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser)); + } + // Execute Web Script transactionedExecuteAs(script, scriptReq, scriptRes); } @@ -443,6 +457,15 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten @Override public Registry getRegistry() { + if (AuthenticationUtil.isMtEnabled()) + { + String user = AuthenticationUtil.getRunAsUser(); + if (user == null) + { + throw new RuntimeException("Failed to getRegistry: need to pre-authenticate in MT environment"); + } + } + String tenantDomain = tenantAdminService.getCurrentUserDomain(); Registry registry = webScriptsRegistryCache.get(tenantDomain); if (registry == null) @@ -452,6 +475,61 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten } return registry; } + + /* (non-Javadoc) + * @see org.alfresco.web.scripts.AbstractRuntimeContainer#onApplicationEvent(org.springframework.context.ApplicationEvent) + */ + @Override + public void onApplicationEvent(ApplicationEvent event) + { + if (event instanceof ContextRefreshedEvent) + { + ContextRefreshedEvent refreshEvent = (ContextRefreshedEvent)event; + ApplicationContext refreshContext = refreshEvent.getApplicationContext(); + if (refreshContext != null && refreshContext.equals(applicationContext)) + { + RunAsWork work = new RunAsWork() + { + public Object doWork() throws Exception + { + reset(); + return null; + } + }; + AuthenticationUtil.runAs(work, AuthenticationUtil.getSystemUserName()); + } + } + } + + /* (non-Javadoc) + * @see org.alfresco.web.scripts.AbstractRuntimeContainer#getRequiredAuthentication() + */ + @Override + public RequiredAuthentication getRequiredAuthentication() + { + if (AuthenticationUtil.isMtEnabled()) + { + return RequiredAuthentication.guest; // user or guest (ie. at least guest) + } + + return RequiredAuthentication.none; + } + + /* (non-Javadoc) + * @see org.alfresco.web.scripts.RuntimeContainer#authenticate(org.alfresco.web.scripts.Authenticator, org.alfresco.web.scripts.Description.RequiredAuthentication) + */ + @Override + public boolean authenticate(Authenticator auth, RequiredAuthentication required) + { + if (auth != null) + { + AuthenticationUtil.clearCurrentSecurityContext(); + + return auth.authenticate(required, false); + } + + return false; + } /* (non-Javadoc) * @see org.alfresco.web.scripts.AbstractRuntimeContainer#reset()