【问题标题】:How can I provide a Spring configuation bean in a WebSecurityConfigurerAdapter for testing?如何在 WebSecurityConfigurerAdapter 中提供 Spring 配置 bean 进行测试?
【发布时间】:2021-06-14 12:58:39
【问题描述】:

我使用以下 SecurityConfiguration 类来保护 Spring Boot 应用程序中的端点。该类依赖于ApiConfiguration 类,该类为内存中的身份验证提供用户名和密码。

当为控制器启动@WebMvcTest 时,Spring 也会尝试初始化安全配置,但无法加载应用程序上下文。

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'ApiConfiguration' available: expected at least 1 bean which qualifies as autowire candidate.

我尝试在测试类中添加MockBean

@MockBean
private ApiConfiguration apiConfiguration;

这解决了上述问题,但是用户名和密码为空。

是否有任何 Spring 支持提供此配置 bean 进行测试?

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration {

    @Configuration
    @Order(1)
    public static class ApiSecurityConfiguration extends WebSecurityConfigurerAdapter {

        private static final String API_USER_ROLE = "API_USER";

        private final ApiConfiguration apiConfig;

        public ApiSecurityConfiguration(ApiConfiguration apiConfig) {
            this.apiConfig = apiConfig;
        }

        @Bean
        PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication()
                    .withUser(apiConfig.getUsername())
                    .password(passwordEncoder().encode(apiConfig.getPassword()))
                    .roles(API_USER_ROLE);
        }

        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity
                    .csrf().disable()
                    .formLogin().disable()
                    .mvcMatcher("/api/**")
                    .authorizeRequests()
                    .anyRequest().hasRole(API_USER_ROLE)
                    .and()
                    .httpBasic()
                    .and()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        }
    }
}

【问题讨论】:

  • 当您使用 @MockBean 时,您是否在 setup/before 方法中为 getUsername()getPassword() 定义了模拟值?
  • @SteveRiesenberg 是的,我做到了。似乎SecurityConfiguration 类在 Mockito 启动之前就被加载了。所以模拟实际上并没有返回任何值。

标签: spring spring-security spring-test


【解决方案1】:

我最终创建了一个带有@TestConfiguration 注释的CustomApiConfiguration。这似乎可以解决问题。至少,Spring 能够在设置SecurityConfiguration 类时读取属性。

@TestConfiguration
public class CustomApiConfiguration {

    @Bean
    public ApiConfiguration apiConfiguration() {
        final ApiConfiguration config = new ApiConfiguration();
        config.setUsername("api-username");
        config.setPassword("api-password");
        return config;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-28
    • 2015-06-16
    • 1970-01-01
    • 2014-02-24
    • 1970-01-01
    • 1970-01-01
    • 2018-02-02
    • 2021-09-18
    相关资源
    最近更新 更多