Spring Security
  1. Spring Security
  2. SEC-1434

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

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.0.2
    • Fix Version/s: 3.0.3, 3.1.0.M1
    • Component/s: Core
    • Labels:
      None
    • Environment:
      Spring: 3.0.1
      Spring Security: 3.0.2

      Description

      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)

      1. gae.log
        87 kB
        Taylor Leese

        Activity

        Hide
        Luke Taylor added a comment - - edited

        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.

        Show
        Luke Taylor added a comment - - edited 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.
        Hide
        Taylor Leese added a comment - - edited

        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"?>
        <beans:beans xmlns="http://www.springframework.org/schema/security"
        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>

        Show
        Taylor Leese added a comment - - edited 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"?> <beans:beans xmlns="http://www.springframework.org/schema/security" 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>
        Hide
        Luke Taylor added a comment -

        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.

        Show
        Luke Taylor added a comment - 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.
        Hide
        Taylor Leese added a comment -

        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

        Show
        Taylor Leese added a comment - 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
        Hide
        Peter Backx added a comment -

        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

        Show
        Peter Backx added a comment - 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
        Hide
        Taylor Leese added a comment -

        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.

        Show
        Taylor Leese added a comment - 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.
        Hide
        Luke Taylor added a comment -

        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.

        Show
        Luke Taylor added a comment - 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.
        Hide
        Taylor Leese added a comment -

        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.

        Show
        Taylor Leese added a comment - 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.
        Hide
        Juergen Hoeller added a comment -

        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

        Show
        Juergen Hoeller added a comment - 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

          People

          • Assignee:
            Luke Taylor
            Reporter:
            Taylor Leese
          • Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: