diff --git a/bundles/server/src/main/java/org/apache/jackrabbit/core/DynamicSecurityManager.java b/bundles/server/src/main/java/org/apache/jackrabbit/core/DynamicSecurityManager.java index ecc397f..5f9e3b7 100644 --- a/bundles/server/src/main/java/org/apache/jackrabbit/core/DynamicSecurityManager.java +++ b/bundles/server/src/main/java/org/apache/jackrabbit/core/DynamicSecurityManager.java @@ -23,6 +23,7 @@ import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import javax.jcr.AccessDeniedException; import javax.jcr.Credentials; @@ -38,6 +39,7 @@ import org.apache.jackrabbit.api.security.principal.PrincipalManager; import org.apache.jackrabbit.api.security.user.Authorizable; import org.apache.jackrabbit.api.security.user.Group; import org.apache.jackrabbit.api.security.user.UserManager; +import org.apache.jackrabbit.core.RepositoryImpl.WorkspaceInfo; import org.apache.jackrabbit.core.config.AccessManagerConfig; import org.apache.jackrabbit.core.config.LoginModuleConfig; import org.apache.jackrabbit.core.config.SecurityConfig; @@ -126,7 +128,7 @@ public class DynamicSecurityManager implements JackrabbitSecurityManager { * key = name of the workspace, * value = {@link AccessControlProvider} */ - private final Map acProviders = new HashMap(); + private final Map acProviders = new ConcurrentHashMap(); /** * the AccessControlProviderFactory @@ -202,13 +204,12 @@ public class DynamicSecurityManager implements JackrabbitSecurityManager { anonymousId = SecurityConstants.ANONYMOUS_ID; } - // create the system userManager and make sure the system-users exist. systemUserManager = createUserManager(this.systemSession); createSystemUsers(systemUserManager, this.systemSession, adminId, anonymousId); // init default ac-provider-factory acProviderFactory = new DynamicAccessControlProviderFactoryImpl(); //Nakamura change - acProviderFactory.init(this.systemSession); + acProviderFactory.init(systemSession); // create the workspace access manager SecurityManagerConfig smc = config.getSecurityManagerConfig(); @@ -220,7 +221,9 @@ public class DynamicSecurityManager implements JackrabbitSecurityManager { log.debug("No WorkspaceAccessManager configured; using default."); workspaceAccessManager = createDefaultWorkspaceAccessManager(); } - workspaceAccessManager.init(this.systemSession); + // Nakamura change + // Dont provide a security Session since if you do it could get bound to the thread incorrectly. + workspaceAccessManager.init(null); // initialize principal-provider registry // 1) create default @@ -241,7 +244,7 @@ public class DynamicSecurityManager implements JackrabbitSecurityManager { public void dispose(String workspaceName) { checkInitialized(); synchronized (acProviders) { - AccessControlProvider prov = acProviders.remove(workspaceName); + AccessControlProviderHolder prov = acProviders.remove(workspaceName); if (prov != null) { prov.close(); } @@ -254,7 +257,7 @@ public class DynamicSecurityManager implements JackrabbitSecurityManager { public void close() { checkInitialized(); synchronized (acProviders) { - for (AccessControlProvider accessControlProvider : acProviders.values()) { + for (AccessControlProviderHolder accessControlProvider : acProviders.values()) { accessControlProvider.close(); } acProviders.clear(); @@ -532,13 +535,6 @@ public class DynamicSecurityManager implements JackrabbitSecurityManager { } /** - * @return The system session used to initialize this SecurityManager. - */ - protected Session getSystemSession() { - return systemSession; - } - - /** * @return The repository used to initialize this SecurityManager. */ protected Repository getRepository() { @@ -557,9 +553,11 @@ public class DynamicSecurityManager implements JackrabbitSecurityManager { private AccessControlProvider getAccessControlProvider(String workspaceName) throws NoSuchWorkspaceException, RepositoryException { checkInitialized(); - AccessControlProvider provider = acProviders.get(workspaceName); + AccessControlProvider provider = getAccessControlProviderHolder(workspaceName).get(); if (provider == null || !provider.isLive()) { - SystemSession systemSession = repository.getSystemSession(workspaceName); + // providers are bound to threads, so we need to create a new SystemSession per provider. + WorkspaceInfo workspaceInfo = repository.getWorkspaceInfo(workspaceName); + SystemSession systemSession = SystemSession.create(repository,workspaceInfo.getConfig()); // mark this session as 'active' so the workspace does not get disposed // by the workspace-janitor until the garbage collector is done // TODO: review again... this workaround is now used in several places. @@ -569,12 +567,23 @@ public class DynamicSecurityManager implements JackrabbitSecurityManager { WorkspaceSecurityConfig secConf = (conf == null) ? null : conf.getSecurityConfig(); synchronized (acProviders) { provider = acProviderFactory.createProvider(systemSession, secConf); - acProviders.put(workspaceName, provider); + getAccessControlProviderHolder(workspaceName).set(provider); } } return provider; } + private AccessControlProviderHolder getAccessControlProviderHolder(String workspaceName) { + synchronized (acProviders) { + AccessControlProviderHolder accessControlProviderHolder = acProviders.get(workspaceName); + if ( accessControlProviderHolder == null ) { + accessControlProviderHolder = new AccessControlProviderHolder(); + acProviders.put(workspaceName, accessControlProviderHolder); + } + return accessControlProviderHolder; + } + } + /** * Make sure the sytem users (admin and anonymous) exist. *