使用spring boot禁用单元测试的安全性

ste*_*ash 34 spring-test spring-boot

我正在尝试用安全性创建一个简单的spring boot web项目.我可以正常启动应用程序,安全性正常.但是,我有一些我想要测试的组件没有安全性(或者根本没有测试 - 我根本无法进行测试).

我得到一个异常,表明它找不到ObjectPostProcessor,因此无法启动容器.

引起:org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到类型为[org.springframework.security.config.annotation.ObjectPostProcessor]的限定bean用于依赖

14:01:50.937 [main] ERROR o.s.boot.SpringApplication - Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fmpdfApplication.ApplicationSecurity': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.setObjectPostProcessor(org.springframework.security.config.annotation.ObjectPostProcessor); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.config.annotation.ObjectPostProcessor] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]
    at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:103) [spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.12.jar:4.12]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) [junit-4.12.jar:4.12]
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) [junit-4.12.jar:4.12]
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) [junit-4.12.jar:4.12]
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163) [spring-test-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137) [junit-4.12.jar:4.12]
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) [junit-rt.jar:na]
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) [junit-rt.jar:na]
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) [junit-rt.jar:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_45]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_45]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_45]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_45]
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) [idea_rt.jar:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.setObjectPostProcessor(org.springframework.security.config.annotation.ObjectPostProcessor); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.config.annotation.ObjectPostProcessor] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:649) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    ... 43 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.config.annotation.ObjectPostProcessor] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:606) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    ... 45 common frames omitted

我甚至没有尝试测试与网络或安全性或任何相关的任何内容.我只是对我的一个组件进行单元测试.我的单元测试(在groovy中)就像:

@RunWith(SpringJUnit4ClassRunner)
@SpringApplicationConfiguration(classes = FmpdfApplication)
@ActiveProfiles(["test", "mockstore"])
class PdfUpdaterTest {

    @Resource PdfUpdater pdfUpdater
    ...
Run Code Online (Sandbox Code Playgroud)

我的(相关)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")
Run Code Online (Sandbox Code Playgroud)

我试过设置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 {
    ..
Run Code Online (Sandbox Code Playgroud)

这是问题的一部分吗?如果有相关的话,有没有办法让这个@Lazy?

更新:如果我将单元测试标记为@WebIntegrationTest,那么一切正常 - 但它会启动一个嵌入式tomcat服务器.如何禁用单元测试非Web事物的弹簧安全性?

Vik*_*lia 42

更新到ANSWER: 我最近学到的另一个选项是,如果我使用MockMvc和AutoConfigureMockMvc来测试我的控制器,我可以在其上设置secure = false以禁用适用于您的控制器的任何安全性.

@AutoConfigureMockMvc(secure = false)
Run Code Online (Sandbox Code Playgroud)

如果没有与下面的基本认证一起使用.


您获得的异常与我获得的异常非常不同,但如果您想在运行测试用例时禁用安全性,则可以尝试使用配置文件并使用测试配置文件的属性禁用基本安全性.这就是我做的 -

  1. @Profile(value = {"development", "production"})为我的实现添加了注释WebSecurityConfigurerAdapter-
    @Configuration
    @EnableWebSecurity
    @Profile(value = {"development", "production"})
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
Run Code Online (Sandbox Code Playgroud)

2.现在,在test/resources,创建application-test.yml以定义测试配置文件的属性并添加此项 -

    # Security enable/disable
    security:
      basic:
        enabled: false
Run Code Online (Sandbox Code Playgroud)

3.现在,对于您的测试用例,添加此注释以应用活动配置文件@ActiveProfiles(value = "test").这就是我班上的样子 -

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = Application.class)
    @WebAppConfiguration
    @ActiveProfiles(value = "test")
    @IntegrationTest({"server.port=0"})
    public class SampleControllerIntegrationTest {
Run Code Online (Sandbox Code Playgroud)

这样做会禁用我的测试用例的安全性,并且我能够访问经过身份验证的URL.我希望这也适合你.祝你好运!

  • @AutoConfigureMockMvc(secure = false) 现已弃用。 (11认同)
  • @andrew17你可以使用`addFilters = false` (4认同)
  • 没有属性 - `secure` (3认同)
  • 接受的答案对我不起作用,我正在使用 OAuth2 并在资源服务器上执行此操作,因此通过 ResourceServerConfigurerAdapter 添加了 @Profile 注释,但其余部分是相同的,并且工作完美。 (2认同)

jum*_*key 29

就我而言,@AutoConfigureMockMvc(addFilters = false)帮助了我。

例子:

@WebMvcTest(MyController.class)
@AutoConfigureMockMvc(addFilters = false)
@TestPropertySource(locations="classpath:application-test.properties")
public class MyControllerTests {
Run Code Online (Sandbox Code Playgroud)

干杯

  • 使用此方法我无法加载 ApplicationContext (2认同)

Sam*_*nen 23

FmpdfApplication可能会注释@EnableAutoConfiguration(或使用@SpringBootApplication元注释@EnableAutoConfiguration),这将导致Spring Security被选中并通过自动配置进行配置.

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

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

@EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class, ManagementSecurityAutoConfiguration.class })
Run Code Online (Sandbox Code Playgroud)

当然,您不希望将它们排除在生产部署之外.因此,您需要有一个单独的@Configuration类进行生产和测试.

问候,

山姆

ps您可能也会发现我对以下问题的回答也很有用:基于Spring-Boot模块的集成测试

  • 仅供参考,我认为 /autoconfig 的东西只有在你将执行器拉入你的 pom.xml 中时才有效。由于我没有它,因此我将“logging.level.org.springframework=DEBUG”放入 src/test/resources/application.properties 中以查看自动配置带来的内容的报告。 (3认同)
  • 请注意,@EnableAutoConfiguration(exclude = {SecurityAutoconfiguration.class, ManagementWebSecurityAutoConfiguration.class}) 将位于 src/test/java 中的 @SpringBootApplication 注释类中。还要注意ManagementWebSecurityAutoConfiguration.class的使用(我使用的是spring boot 1.3.0) (2认同)

小智 8

尝试这个禁用弹簧启动安全性进行测试


@AutoConfigureMockMvc(secure = false)

@RunWith(SpringRunner.class)
@WebMvcTest(SampleController.class)
@AutoConfigureMockMvc(secure = false)
public class SampleControllerIntegrationTest {
Run Code Online (Sandbox Code Playgroud)

  • 现在这已被弃用。 (5认同)
  • 根据您的用例,您可以使用“@AutoConfigureMockMvc(addFilters = false)”代替。 (3认同)

Han*_*tsy 7

尝试使用 Spring Security@WithMockUser在测试中快速模拟用户。

http://docs.spring.io/spring-security/site/docs/4.0.x/reference/htmlsingle/#test