我正在尝试创建一个具有安全性的简单 Spring Boot Web 项目。我可以很好地启动应用程序并且安全工作正常。但是,我有一些组件想要在没有安全性的情况下进行测试(或者根本无法测试——我根本无法让测试工作)。
我收到一个异常,表明它找不到 ObjectPostProcessor,因此无法启动容器。
原因:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖找到[org.springframework.security.config.annotation.ObjectPostProcessor]类型的合格bean
14:01:50.937 [main] 错误 osboot.SpringApplication - 应用程序启动失败
org.springframework.beans.factory.BeanCreationException:创建名为“fmpdfApplication.ApplicationSecurity”的bean时出错:注入自动装配的依赖项失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配方法:public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.setObjectPostProcessor(org.springframework.security.config.annotation.ObjectPostProcessor) ;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项找到类型 [org.springframework.security.config.annotation.ObjectPostProcessor] 的合格 bean:预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖注释:{}
在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]
在 org.springframework.boot.SpringApplication.run(SpringApplication.java:320) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]
在 org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:103) [spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]
在 org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
在 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
在 org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.junit.runner.JUnitCore.run(JUnitCore.java:137) [junit-4.12.jar:4.12]
在 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) [junit-rt.jar:na]
在 com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) [junit-rt.jar:na]
在 com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) [junit-rt.jar:na]
在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_45]
在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_45]
在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_45]
在 java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_45]
在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) [idea_rt.jar:na]
引起:org.springframework.beans.factory.BeanCreationException:无法自动装配方法:public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.setObjectPostProcessor(org.springframework.security.config.annotation.ObjectPostProcessor) ;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项找到类型 [org.springframework.security.config.annotation.ObjectPostProcessor] 的合格 bean:预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖注释:{}
在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:649) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
...省略了43个常用框架
原因:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖找到[org.springframework.security.config.annotation.ObjectPostProcessor]类型的合格bean:预计至少有1个bean有资格作为此依赖的自动装配候选者。依赖注释:{}
在 org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:606) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
...省略了45个常用框架
我什至没有尝试测试与网络或安全相关的任何内容。我只是对我的一个组件进行单元测试。我的单元测试(在 groovy 中)就像:
@RunWith(SpringJUnit4ClassRunner)
@SpringApplicationConfiguration(classes = FmpdfApplication)
@ActiveProfiles(["test", "mockstore"])
class PdfUpdaterTest {
@Resource PdfUpdater pdfUpdater
...
我的(相关)gradle依赖项是:
compile("org.springframework.boot:spring-boot-starter-actuator")
compile("org.springframework.boot:spring-boot-starter-security")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-jdbc")
testCompile("org.springframework.boot:spring-boot-starter-test")
我试过设置 management.security.enabled=false security.basic.enabled=false 但这没有帮助
另一个相关信息:我需要自定义安全性,因此我遵循以下模式:
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
..
这是问题的一部分吗?如果相关,有没有办法制作这个@Lazy?
更新:如果我将单元测试标记为@WebIntegrationTest,那么一切正常——但它会启动一个嵌入式 tomcat 服务器。如何禁用 Spring Security 以对非 Web 事物进行单元测试?
原文由 steve_ash 发布,翻译遵循 CC BY-SA 4.0 许可协议
FmpdfApplication
is likely annotated with@EnableAutoConfiguration
(or with@SpringBootApplication
which is meta-annotated with@EnableAutoConfiguration
), and this will lead to Spring Security通过自动配置获取和配置。如果您想查看正在自动配置的内容,请启动您的 Web 应用程序并访问
autoconfig
端点(例如 http://localhost:8080/autoconfig )。然后搜索“安全”以查看正在检测哪些“自动配置”类。然后,您可以通过排除这些类来禁用安全性的自动配置,如下所示:
当然,您不希望将它们排除在生产部署之外。因此,您需要有一个单独的
@Configuration
用于生产和测试的类。问候,
山姆
ps 您可能还会发现我对以下问题的回答也很有用: 基于 Spring-Boot 模块的集成测试