Hi Rory,
Rory Douglas schrieb:
Apologies if this is a repeat, my first post didn't seem to make it:
And apologies for not replying earlier...
Thanks for reporting this tricky issue ;-)
Well, this is quite a tricky situation here....
Let me explain quickly what is going on:
* The JspScriptEngineFactory is activating
and setting the Thread Context Loader
* This loader is actually a facade which
accesses the real loader on demand
* While the real loader is loaded and because
(as you noted) the Session user ID does
not match the expected id, an impersonation
takes place.
* While impersonating a class needs being loaded.
* This class loading uses the thread context
loader which is the facade and which in turn
tries to create the real loader (again).
Now, I see two problems: (1) Prevent the
RepositoryClassLoaderFacade.getDelegateeClassLoader() from being called
recursively and (2) fix the issue of non-matching id's.
The first issue, might be solved by having the getDelegateeClassLoader()
method set a temporary no-op delegatee while setting up the real
delegatee. Another possible solution would be temporarily switch the
thread context class loader. I am more inclined to the former approach.
The second issue is probably really a Jackrabbit one, as you already
reported the Jackrabbit issue with respect to extracting the user id out
of the Session's subject. As a short-term solution in Sling we could
just switch of support for "per-user" repository class loaders or we
could add configuration to switch on/off such support. (This
functionality is not used at the moment any way)
Any more opinions on these solutions/approaches ?
Regards
Felix
I disabled the SimpleLoginModule in repository.xml and configured a
login.conf file with the com.sun.security.auth.module.
LdapLoginModule (from JDK 6). After creating LDAP users for the admin &
anonymous identities, Sling starts up fine.
However, when requesting a node with a JSP rendering script, the
JspScriptEngineFactory throws an ClassCircularityError on activate - it
seems to be looping in the RepositoryClassLoader as it tries to login to
the repository (stack trace is below). I debugged through this and find
that RepositoryClassLoaderProviderImpl has this code in
getSession(String owner):
if (admin.getUserID().equals(owner)) {
return admin;
}
otherwise it tries to impersonate the "owner". I've verified that by
commenting out the owner check & always returning the admin session, the
ClassCircularityError doesn't occur.
When using LdapLoginModule, the userID returned from Session is the full
LDAP distinguished name (uid=admin,ou=People,ou=test1,o=test.com
<http://test.com>),while owner is just "admin". This occurs because the
Jackrabbit SessionImpl class just grabs the first Principal from the
Subject when it is initialized, and that principal is LdapPrincipal in
the case of the LdapLoginModule. The LoginModule actually adds another
(UserPrincipal), whose name is just "admin", but this is not used or
checked.
I'm not sure what the right approach to fix this is. It would be good
if RepositoryClassLoaderProviderImpl checked the owner string against
all Principal names in the Session's Subject. However, Session doesn't
expose it's Subject, so you can't do this. And there doesn't seem to be
a way to tell Jackrabbit which Principal to choose (like specify it
should use first instance of UserPrincipal, or first Principal whose
name matches some regex). The last option appears to be rewriting the
LoginModule to store the UserPrincipal first, which isn't desirable (and
may not be possible for other LoginModules).
15.08.2008 12:25:24.171 **ERROR** [SCR Component Actor]
org.apache.sling.scripting.jsp
[org.apache.sling.scripting.jsp.JspScriptEngineFactory] The activate
method has thrown an exception (java.lang.ClassCircularityError:
com/sun/security/auth/module/LdapLoginModule)
java.lang.ClassCircularityError:
com/sun/security/auth/module/LdapLoginModule
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:731)
at
javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at
javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
at javax.security.auth.login.LoginContext.login(LoginContext.java:579)
at
org.apache.jackrabbit.core.security.AuthContext$JAAS.login(AuthContext.java:88)
at
org.apache.jackrabbit.core.RepositoryImpl.login(RepositoryImpl.java:1245)
at
org.apache.sling.jcr.base.internal.SessionPool.acquireSession(SessionPool.java:268)
at
org.apache.sling.jcr.base.internal.SessionPoolManager.login(SessionPoolManager.java:99)
at
org.apache.sling.jcr.base.AbstractSlingRepository.login(AbstractSlingRepository.java:240)
at
org.apache.sling.jcr.base.AbstractSlingRepository.loginAdministrative(AbstractSlingRepository.java:206)
at
org.apache.sling.jcr.classloader.internal.RepositoryClassLoaderProviderImpl.getSession(RepositoryClassLoaderProviderImpl.java:103)
at
org.apache.sling.jcr.classloader.internal.RepositoryClassLoaderFacade.getSession(RepositoryClassLoaderFacade.java:185)
at
org.apache.sling.jcr.classloader.internal.RepositoryClassLoaderFacade.getDelegateClassLoader(RepositoryClassLoaderFacade.java:195)
at
org.apache.sling.jcr.classloader.internal.RepositoryClassLoaderFacade.loadClass(RepositoryClassLoaderFacade.java:105)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:731)
at
javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at
javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
at javax.security.auth.login.LoginContext.login(LoginContext.java:579)
at
org.apache.jackrabbit.core.security.AuthContext$JAAS.login(AuthContext.java:88)
at
org.apache.jackrabbit.core.RepositoryImpl.login(RepositoryImpl.java:1245)
at
org.apache.jackrabbit.core.SessionImpl.impersonate(SessionImpl.java:810)
at
org.apache.sling.jcr.base.internal.SessionPool.acquireSession(SessionPool.java:330)
at
org.apache.sling.jcr.base.internal.SessionPoolManager.impersonate(SessionPoolManager.java:127)
at
org.apache.sling.jcr.base.internal.PooledSession.impersonate(PooledSession.java:220)
at
org.apache.sling.jcr.classloader.internal.RepositoryClassLoaderProviderImpl.getSession(RepositoryClassLoaderProviderImpl.java:112)
at
org.apache.sling.jcr.classloader.internal.RepositoryClassLoaderFacade.getSession(RepositoryClassLoaderFacade.java:185)
at
org.apache.sling.jcr.classloader.internal.RepositoryClassLoaderFacade.getDelegateClassLoader(RepositoryClassLoaderFacade.java:195)
at
org.apache.sling.jcr.classloader.internal.RepositoryClassLoaderFacade.getResource(RepositoryClassLoaderFacade.java:114)
at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:1168)
at javax.xml.parsers.SecuritySupport$4.run(SecuritySupport.java:96)
at java.security.AccessController.doPrivileged(Native Method)
at
javax.xml.parsers.SecuritySupport.getResourceAsStream(SecuritySupport.java:89)
at
javax.xml.parsers.FactoryFinder.findJarServiceProvider(FactoryFinder.java:250)
at javax.xml.parsers.FactoryFinder.find(FactoryFinder.java:223)
at
javax.xml.parsers.DocumentBuilderFactory.newInstance(DocumentBuilderFactory.java:123)
at
org.apache.sling.scripting.jsp.jasper.xmlparser.ParserUtils.parseXMLDocument(ParserUtils.java:89)
at
org.apache.sling.scripting.jsp.jasper.xmlparser.ParserUtils.parseXMLDocument(ParserUtils.java:133)
at
org.apache.sling.scripting.jsp.SlingTldLocationsCache.getUriFromTld(SlingTldLocationsCache.java:159)
at
org.apache.sling.scripting.jsp.SlingTldLocationsCache.addBundle(SlingTldLocationsCache.java:125)
at
org.apache.sling.scripting.jsp.SlingTldLocationsCache.<init>(SlingTldLocationsCache.java:56)
at
org.apache.sling.scripting.jsp.JspScriptEngineFactory.activate(JspScriptEngineFactory.java:188)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.apache.felix.scr.impl.ImmediateComponentManager.createImplementationObject(ImmediateComponentManager.java:226)
at
org.apache.felix.scr.impl.ImmediateComponentManager.createComponent(ImmediateComponentManager.java:133)
at
org.apache.felix.scr.impl.DelayedComponentManager.getService(DelayedComponentManager.java:83)
at
org.apache.felix.framework.ServiceRegistrationImpl.getFactoryUnchecked(ServiceRegistrationImpl.java:256)
at
org.apache.felix.framework.ServiceRegistrationImpl.getService(ServiceRegistrationImpl.java:190)
at
org.apache.felix.framework.ServiceRegistry.getService(ServiceRegistry.java:291)
at org.apache.felix.framework.Felix.getService(Felix.java:2842)
at
org.apache.felix.framework.BundleContextImpl.getService(BundleContextImpl.java:417)
at
org.apache.felix.scr.impl.DependencyManager.getService(DependencyManager.java:560)
at
org.apache.felix.scr.impl.DependencyManager.invokeBindMethod(DependencyManager.java:858)
at
org.apache.felix.scr.impl.DependencyManager.serviceAdded(DependencyManager.java:190)
at
org.apache.felix.scr.impl.DependencyManager.serviceChanged(DependencyManager.java:115)
at
org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:765)
at
org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:623)
at
org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:554)
at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:3612)
at org.apache.felix.framework.Felix.access$000(Felix.java:36)
at org.apache.felix.framework.Felix$1.serviceChanged(Felix.java:626)
at
org.apache.felix.framework.ServiceRegistry.fireServiceChanged(ServiceRegistry.java:559)
at
org.apache.felix.framework.ServiceRegistry.registerService(ServiceRegistry.java:75)
at org.apache.felix.framework.Felix.registerService(Felix.java:2702)
at
org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:254)
at
org.apache.felix.scr.impl.AbstractComponentManager.registerComponentService(AbstractComponentManager.java:698)
at
org.apache.felix.scr.impl.AbstractComponentManager.activateInternal(AbstractComponentManager.java:506)
at
org.apache.felix.scr.impl.AbstractComponentManager.enableInternal(AbstractComponentManager.java:398)
at
org.apache.felix.scr.impl.AbstractComponentManager.access$000(AbstractComponentManager.java:36)
at
org.apache.felix.scr.impl.AbstractComponentManager$1.run(AbstractComponentManager.java:99)
at
org.apache.felix.scr.impl.ComponentActorThread.run(ComponentActorThread.java:85)