一尘不染

使用Spring Boot禁用单元测试的安全性

spring-boot

我正在尝试创建一个具有安全性的简单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(本机方法)〜[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个通用框架

我什至不尝试测试与Web或安全性相关的任何内容。我只是对我的组件之一进行单元测试。我的单元测试(常规)如下:

@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服务器。如何为非Web事物的单元测试禁用Spring Security?


阅读 253

收藏
2020-05-30

共1个答案

一尘不染

FmpdfApplication可能用标记@EnableAutoConfiguration(或用@SpringBootApplication进行元标记@EnableAutoConfiguration),这将导致通过自动配置选择和配置Spring
Security。

如果要查看正在自动配置的内容,请启动Web应用程序并访问autoconfig端点(例如,http:// localhost:8080 /
autoconfig
)。然后搜索“安全性”以查看检测到哪些“自动配置”类。

然后,可以通过排除以下类来禁用安全性的自动配置:

@EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class, ManagementSecurityAutoConfiguration.class })

当然,您不会希望将它们排除在生产部署之外。因此,您需要@Configuration为生产和测试创建一个单独的类。

2020-05-30