gpt4 book ai didi

java - Spring安全循环bean依赖错误

转载 作者:太空宇宙 更新时间:2023-11-04 07:06:31 25 4
gpt4 key购买 nike

使用自定义访问决策管理器设置 spring security 方法身份验证 时,我收到循环 bean 依赖项错误,该错误会中止服务器启动。

自定义访问决策管理器从数据库读取安全引用数据,使用的服务也在应用程序的其他地方使用,并且本身是安全的:

我正在使用 spring security 3.0.5,这是主要错误消息(请参阅下面的完整堆栈跟踪):

Error creating bean with name 'securityReferenceDataService': Bean with name 'securityReferenceDataService' has been injected into other beans [myAccessDecisionManager] in its raw version as part of a circular reference, but has eventually been wrapped.

这是 global-security-method 元素和安全引用数据服务的 spring 配置:

<bean id="myAccessDecisionManager" class="sample.mvc.root.context.services.MyAccessDecisionManager">
<property name="securityReferenceDataService" ref="securityReferenceDataService"/>
</bean>

<security:global-method-security secured-annotations="enabled"
jsr250-annotations="enabled" access-decision-manager-ref="myAccessDecisionManager" />

这是安全引用数据服务的简化代码:

public class SecurityReferenceDataDao {

@Secured(value = "ADMIN")
public List<SecurityReferenceData> loadSecurityReferenceData() {
...
}
}

完整堆栈跟踪:

 org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'securityReferenceDataService': Bean with name 'securityReferenceDataService' has been injected into other beans [myAccessDecisionManager] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:551)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:549)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1282)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:518)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:499)
at org.mortbay.jetty.plugin.Jetty6PluginWebAppContext.doStart(Jetty6PluginWebAppContext.java:115)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:156)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:152)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
at org.mortbay.jetty.Server.doStart(Server.java:224)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.plugin.Jetty6PluginServer.start(Jetty6PluginServer.java:132)
at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:454)
at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:396)
at org.mortbay.jetty.plugin.Jetty6RunWar.execute(Jetty6RunWar.java:67)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:106)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
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:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:317)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:152)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:555)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:158)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
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:46)

最佳答案

问题在于自定义访问决策管理器使用的引用数据服务本身是通过 @Secured 进行保护的。

这会导致这样一种情况:要创建访问决策管理器,我们需要将其包装在需要访问决策管理器的安全代理中,需要安全引用数据服务,需要包装在链接到访问决策管理器的代理中,...等等。

其工作方式是,global-method-security元素(在非aspectJ模式下)导致spring security注册一个安全顾问MethodSecurityMetadataSourceAdvisor,它将应用于任何包含至少一个@Secured注释的bean。

要解决循环注入(inject)问题,解决方案是将引用数据服务的非安全版本传递给自定义访问决策管理器,该版本不应用安全方面。有两种方法可以做到这一点:

使用 spring security run-as-manager-ref 解决方案:

一种方法是使用 spring security 3.1 有一个 Run-As使用 Global-method-security 的属性 run-as-manager-ref 使方法安全访问决策管理器以给定角色而不是当前用户的角色运行的机制。

使用内部 bean:

在使用最常见的编织机制(JDK 或 CGLIB 代理)应用方面的应用程序中,也可以使用内部 bean 来解决这个问题:

<bean id="myAccessDecisionManager" class="sample.mvc.root.context.services.MyAccessDecisionManager">
<property name="securityReferenceDataService">
<bean class="sample.mvc.root.context.services.SecurityReferenceDataDao"/>
</property>
</bean>

注意:如果使用加载时或编译时编织,这将不起作用

关于java - Spring安全循环bean依赖错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21293897/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com