SEC-1434: Google App Engine - 'org.springframework.security.filterChainProxy': Initialization of bean failed (java.security.AccessControlException) #1677

Closed
spring-issuemaster opened this Issue Mar 8, 2010 · 9 comments

1 participant

@spring-issuemaster

Taylor Leese (Migrated from SEC-1434) said:

The combination of Spring 3.0.1 and Spring Security 3.0.2 on Google App engine lead to the exception below. Note, the combination of Spring 3.0.1 and Spring Security 3.0.1 does not have this issue.

Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChainProxy': Initialization of bean failed; nested exception is java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader):
java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:355)
at java.security.AccessController.checkPermission(AccessController.java:567)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at com.google.apphosting.runtime.security.CustomSecurityManager.checkPermission(CustomSecurityManager.java:45)
at java.lang.ClassLoader.getSystemClassLoader(Unknown Source)
at org.springframework.beans.BeanUtils.findEditorByConvention(BeanUtils.java:392)
at org.springframework.beans.TypeConverterDelegate.findDefaultEditor(TypeConverterDelegate.java:360)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:213)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:104)
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:419)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:657)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:192)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:984)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:886)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:479)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:270)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:125)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedMap(BeanDefinitionValueResolver.java:382)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:161)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1305)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:557)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:842)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:416)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:261)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:192)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:530)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:135)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1218)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:500)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:448)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.createHandler(AppVersionHandlerMap.java:191)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.getHandler(AppVersionHandlerMap.java:168)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:123)
at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:235)
at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:5485)
at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:5483)
at com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24)
at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:363)
at com.google.net.rpc.impl.Server$2.run(Server.java:837)
at com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56)
at com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:536)
at com.google.net.rpc.impl.Server.startRpc(Server.java:792)
at com.google.net.rpc.impl.Server.processRequest(Server.java:367)
at com.google.net.rpc.impl.ServerConnection.messageReceived(ServerConnection.java:448)
at com.google.net.rpc.impl.RpcConnection.parseMessages(RpcConnection.java:319)
at com.google.net.rpc.impl.RpcConnection.dataReceived(RpcConnection.java:290)
at com.google.net.async.Connection.handleReadEvent(Connection.java:474)
at com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:774)
at com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:205)
at com.google.net.async.EventDispatcher.loop(EventDispatcher.java:101)
at com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:251)
at com.google.apphosting.runtime.JavaRuntime$RpcRunnable.run(JavaRuntime.java:394)
at java.lang.Thread.run(Unknown Source)

@spring-issuemaster

Luke Taylor said:

There aren't actually any Spring Security classes in this stacktrace, so it is a problem initializing the bean factory because of Google's SecurityManager restrictions. If possible, please provide some indication of what is actually being instantiated when this error occurs.

@spring-issuemaster

Taylor Leese said:

Below is my spring security related configuration file (applicationContext-security.xml) and my web.xml. It sounds like this is what you are looking for, but if you need more info please let me know.

applicationContext-security.xml:

<?xml version="1.0" encoding="UTF-8"?>
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">

<http auto-config="false">
    <intercept-url pattern="/css/**" filters="none" />
    <intercept-url pattern="/img/**" filters="none" />
    <intercept-url pattern="/js/**" filters="none" />
    <intercept-url pattern="/app/admin/**" filters="none" />
<intercept-url pattern="/app/login/**" filters="none" />
<intercept-url pattern="/app/register/**" filters="none" />
<intercept-url pattern="/app/error/**" filters="none" />
<intercept-url pattern="/" filters="none" />
<intercept-url pattern="/**" access="ROLE_USER" />
<logout logout-success-url="/" />
<form-login login-page="/app/login" default-target-url="/" authentication-failure-url="/app/login?login_error=1" />
<session-management invalid-session-url="/app/login" />
<remember-me services-ref="rememberMeServices" key="myKey" />
</http>

<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userDetailsService">
        <password-encoder hash="sha-256" base64="true">
            <salt-source user-property="username" />
        </password-encoder>
    </authentication-provider>
</authentication-manager>

<beans:bean id="userDetailsService" class="com.my.service.auth.UserDetailsServiceImpl" />

<beans:bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
    <beans:property name="userDetailsService" ref="userDetailsService" />
    <beans:property name="tokenRepository" ref="persistentTokenRepository" />
    <beans:property name="key" value="myKey" />
</beans:bean>

<beans:bean id="persistentTokenRepository" class="com.my.service.auth.PersistentTokenRepositoryImpl" />

/beans:beans

@spring-issuemaster

Luke Taylor said:

Thanks, but it would be helpful to know what the actual bean type is that's being created. This should be output in the debug log from AbstractAutowireCapableBeanFactory.

@spring-issuemaster

Taylor Leese said:

Attached is the relevant portion of the logs from GAE. I added below to my logging.properties file:

org.springframework.beans.factory.support.level=FINEST

@spring-issuemaster

Peter Backx said:

FYI,

There is some discussion on this topic at Stack Overflow:
http://stackoverflow.com/questions/2335244/google-app-engine-spring-security-issue-java-security-accesscontrolexception

It seems to be related to a call to BeanUtils.findEditorByConvention

@spring-issuemaster

Taylor Leese said:

Yes, that is the question I asked on SO. The BeanUtils.findEditorByConvention call throws an exception because it tries to get the ClassLoader and App Engine doesn't allow it. However, what isn't clear is why this exception is only thrown with Spring Security 3.0.2 and not Spring Security 3.0.1.

@spring-issuemaster

Luke Taylor said:

This appears to happen with much simpler configurations - anything using the http namespace in GAE. It seems to be due to using a BeanDefinition with type java.lang.String (when creating the "universal match" pattern in the FilterChainProxy). The changes for SEC-1407 mean that it shouldn't be relevant for the 3.1 branch (master) as the relevant code no longer exists.

I've modified the 3.0.x branch to use a plain String for the universal match key, which should fix the problem there too.

@spring-issuemaster

Taylor Leese said:

This appears to have fixed this specific issue, but I'm still having other issues with remember me and GAE. I posted an question (http://forum.springsource.org/showthread.php?p=289581#post289581) that describes the issue I'm having. I'm not sure if this is another bug or me doing something wrong.

@spring-issuemaster

Juergen Hoeller said:

As of Spring 3.0.2, the Spring BeanUtils class catches an AccessControlException in findEditorByConvention and silently skips the JavaBeans system editor check then. That should sort out the core issue underneath this one here.

Juergen

@spring-issuemaster spring-issuemaster added this to the 3.1.0.M1 milestone Feb 5, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment