Uploaded image for project: 'ZK Spring'
  1. ZK Spring
  2. ZKSPRING-56

Upgrade to work with Spring Security 4

    Details

    • Type: New Feature
    • Status: Closed
    • Priority: Normal
    • Resolution: Won't Do
    • Affects Version/s: 3.2.0
    • Fix Version/s: 4.0.0
    • Component/s: security
    • Labels:
      None

      Description

      Due to several API changes between Spring 3 and 4 zkspring-security needs to be upgraded in order to work with Spring 4.
      According to cve-2018-1199, we need to upgrade to 4.2.4 or above

        Activity

        Hide
        hawk hawk added a comment - - edited

        AccessDecisionManager does not support secure object class: class org.zkoss.zk.ui.event.Event

        steps to reproduce

        When starting zkspringissue project,

        SEVERE: Context initialization failed
        org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'zkEventProcessInterceptor': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: AccessDecisionManager does not support secure object class: class org.zkoss.zk.ui.event.Event
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
        at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:800)
        at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:444)
        at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:791)
        at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:294)
        at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349)
        at org.eclipse.jetty.maven.plugin.JettyWebAppContext.startWebapp(JettyWebAppContext.java:297)
        at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1342)
        at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:741)
        at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:505)
        at org.eclipse.jetty.maven.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:366)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
        at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
        at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:163)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
        at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
        at org.eclipse.jetty.server.Server.start(Server.java:387)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
        at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
        at org.eclipse.jetty.server.Server.doStart(Server.java:354)
        at org.eclipse.jetty.maven.plugin.JettyServer.doStart(JettyServer.java:73)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
        at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:535)
        at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:358)
        at org.eclipse.jetty.maven.plugin.JettyRunMojo.execute(JettyRunMojo.java:167)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:199)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
        at org.codehaus.classworlds.Launcher.main(Launcher.java:47)
        Caused by: java.lang.IllegalArgumentException: AccessDecisionManager does not support secure object class: class org.zkoss.zk.ui.event.Event
        at org.springframework.util.Assert.isTrue(Assert.java:92)
        at org.springframework.security.access.intercept.AbstractSecurityInterceptor.afterPropertiesSet(AbstractSecurityInterceptor.java:144)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
        ... 65 more

        Root cause

        default AccessDecisionManager created by <http> contains 3 voter, only RoleVoter supports any class of secure object. Other 2 don't support. If any voter doesn't support the class of the secure object, spring will throw the exception above.

        public abstract class AbstractSecurityInterceptor implements InitializingBean,
        		ApplicationEventPublisherAware, MessageSourceAware {
        
        ...
            public void afterPropertiesSet() throws Exception {
                ...
                Assert.isTrue(this.accessDecisionManager.supports(getSecureObjectClass()),
                        "AccessDecisionManager does not support secure object class: "
                                + getSecureObjectClass());
        

        ref:

        solution

        • define a custom access decisition manager with RoleVoter only
          	<b:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
          		<b:constructor-arg>
          			<b:list>
          				<b:bean class="org.springframework.security.access.vote.RoleVoter" />
          			</b:list>
          		</b:constructor-arg>
          	</b:bean>
          <http auto-config="true" use-expressions="false" access-decision-manager-ref="accessDecisionManager" >
          ...
          </http>
          
        Show
        hawk hawk added a comment - - edited AccessDecisionManager does not support secure object class: class org.zkoss.zk.ui.event.Event steps to reproduce When starting zkspringissue project, SEVERE: Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'zkEventProcessInterceptor': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: AccessDecisionManager does not support secure object class: class org.zkoss.zk.ui.event.Event at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:800) at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:444) at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:791) at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:294) at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349) at org.eclipse.jetty.maven.plugin.JettyWebAppContext.startWebapp(JettyWebAppContext.java:297) at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1342) at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:741) at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:505) at org.eclipse.jetty.maven.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:366) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132) at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114) at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61) at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:163) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132) at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114) at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132) at org.eclipse.jetty.server.Server.start(Server.java:387) at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114) at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61) at org.eclipse.jetty.server.Server.doStart(Server.java:354) at org.eclipse.jetty.maven.plugin.JettyServer.doStart(JettyServer.java:73) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:535) at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:358) at org.eclipse.jetty.maven.plugin.JettyRunMojo.execute(JettyRunMojo.java:167) at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80) at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51) at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128) at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307) at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193) at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106) at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863) at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288) at org.apache.maven.cli.MavenCli.main(MavenCli.java:199) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289) at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229) at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415) at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356) at org.codehaus.classworlds.Launcher.main(Launcher.java:47) Caused by: java.lang.IllegalArgumentException: AccessDecisionManager does not support secure object class: class org.zkoss.zk.ui.event.Event at org.springframework.util.Assert.isTrue(Assert.java:92) at org.springframework.security.access.intercept.AbstractSecurityInterceptor.afterPropertiesSet(AbstractSecurityInterceptor.java:144) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ... 65 more Root cause default AccessDecisionManager created by <http> contains 3 voter, only RoleVoter supports any class of secure object. Other 2 don't support. If any voter doesn't support the class of the secure object, spring will throw the exception above. public abstract class AbstractSecurityInterceptor implements InitializingBean, ApplicationEventPublisherAware, MessageSourceAware { ... public void afterPropertiesSet() throws Exception { ... Assert.isTrue( this .accessDecisionManager.supports(getSecureObjectClass()), "AccessDecisionManager does not support secure object class: " + getSecureObjectClass()); ref: https://bitsofinfo.wordpress.com/2009/07/22/accessdecisionmanager-does-not-support-secure-object-class/ solution define a custom access decisition manager with RoleVoter only <b:bean id= "accessDecisionManager" class= "org.springframework.security.access.vote.AffirmativeBased" > <b:constructor-arg> <b:list> <b:bean class= "org.springframework.security.access.vote.RoleVoter" /> </b:list> </b:constructor-arg> </b:bean> <http auto-config= "true" use-expressions= "false" access-decision-manager-ref= "accessDecisionManager" > ... </http>
        Hide
        hawk hawk added a comment - - edited

        Deprecated API

        some Spring security 3 API we call are removed in spring security 4 and show compiling errors.

        solution

        replace them with compatible API, please see the commit.

        Show
        hawk hawk added a comment - - edited Deprecated API some Spring security 3 API we call are removed in spring security 4 and show compiling errors. solution replace them with compatible API, please see the commit .
        Hide
        hawk hawk added a comment -

        zk au requests are blocked after login

        root Cause

        different access configuration in spring 4

        solution

        allow anonymous access: no specify or specify both ROLE_ANONYMOUS, ROLE_USER

        <http>
            ...
            <intercept-url pattern="/**" access="ROLE_ANONYMOUS, ROLE_USER" />
        </http>    
        
        Show
        hawk hawk added a comment - zk au requests are blocked after login root Cause different access configuration in spring 4 solution allow anonymous access: no specify or specify both ROLE_ANONYMOUS, ROLE_USER <http> ... <intercept-url pattern= "/**" access= "ROLE_ANONYMOUS, ROLE_USER" /> </http>
        Hide
        hawk hawk added a comment - - edited

        default login template can't load the login page

        root Cause

        spring security 4 adds default response header x-frame-options: deny. Such option blocks the iframe in default login template from loading the login page.

        solution

        set x-frame option

        <http >
            ...
            <headers>
                <frame-options policy="SAMEORIGIN" />
            </headers>
        </http>
        
        Show
        hawk hawk added a comment - - edited default login template can't load the login page root Cause spring security 4 adds default response header x-frame-options: deny. Such option blocks the iframe in default login template from loading the login page. solution set x-frame option <http > ... <headers> <frame-options policy= "SAMEORIGIN" /> </headers> </http>
        Hide
        hawk hawk added a comment -

        after login success, client requests /zk_error_403

        after success login, au requests to
        ./zul/zkspring/security/loginOKTemplate.zul?loginOKUrl=./zul/zkspring/security/loginOK.zul&loginOKDelay=5
        throw accessDeniedException

        Root Cause

        zk event security blocks it by the config below
        <zksp:intercept-event path="/**" access="ROLE_ANONYMOUS" />

        solution

        remove to secure /zkau or specify both "ROLE_ANONYMOUS, ROLE_USER" like:
        <zksp:intercept-event path="/**" access="ROLE_ANONYMOUS, ROLE_USER" />

        Show
        hawk hawk added a comment - after login success, client requests /zk_error_403 after success login, au requests to ./zul/zkspring/security/loginOKTemplate.zul?loginOKUrl= ./zul/zkspring/security/loginOK.zul&loginOKDelay=5 throw accessDeniedException Root Cause zk event security blocks it by the config below <zksp:intercept-event path="/**" access="ROLE_ANONYMOUS" /> solution remove to secure /zkau or specify both "ROLE_ANONYMOUS, ROLE_USER" like: <zksp:intercept-event path="/**" access="ROLE_ANONYMOUS, ROLE_USER" />
        Hide
        hawk hawk added a comment -

        CSRF stops ajax login pop

        spring 4 by default, authentication requires a CSRF token sent via an http request.

        solution

        disable CSRF

        <http>
        ...
        	<csrf disabled="true"/>
        </http>
        
        Show
        hawk hawk added a comment - CSRF stops ajax login pop spring 4 by default, authentication requires a CSRF token sent via an http request. solution disable CSRF <http> ... <csrf disabled= "true" /> </http>
        Hide
        cor3000 cor3000 added a comment -

        deprecated / obsolete features have been removed, not causing the issues mentioned above

        Show
        cor3000 cor3000 added a comment - deprecated / obsolete features have been removed, not causing the issues mentioned above

          People

          • Assignee:
            henrichen henrichen
            Reporter:
            cor3000 cor3000
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: