【问题标题】:How to use spring security in integration tests?如何在集成测试中使用 Spring Security?
【发布时间】:2021-05-17 20:22:45
【问题描述】:

我有以下WebSecurityConfigurerAdapter 实现:

@Configuration
@Order(0)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    private static final List<String> permittedPaths = asList();
    private static final String protectedPath = "";

    private final UserDetailsServiceImpl userDetailsService;
    private final JwtAuthenticationProvider jwtAuthenticationProvider;
    private final DataSource dataSource;

    public SecurityConfiguration(
        UserDetailsServiceImpl userDetailsService,
        JwtAuthenticationProvider jwtAuthenticationProvider,
        DataSource dataSource
    ) {
        this.userDetailsService = userDetailsService;
        this.jwtAuthenticationProvider = jwtAuthenticationProvider;
        this.dataSource = dataSource;
    }

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

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {}

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
        auth.authenticationProvider(jwtAuthenticationProvider);
        auth.jdbcAuthentication().dataSource(dataSource)
                .usersByUsernameQuery("")
                .authoritiesByUsernameQuery("")
                .passwordEncoder(passwordEncoder());
    }
}

此安全性适用于正常运行的应用程序。但在测试中 - 失败了。 我有一个集成测试,例如:

@WebMvcTest(SomeController.class)
@Import({ErrorHandlerConfiguration.class})
class SomeControllerItTest {
    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private RegistrationService registrationService;

    @Test
    void shouldConfirmRegistration() {}
}

运行后出现以下错误:

原因: org.springframework.beans.factory.UnsatisfiedDependencyException: 创建文件中定义的名称为“securityConfiguration”的 bean 时出错 [SecurityConfiguration.class]:表示不满足的依赖关系 通过构造函数参数0;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 否 'UserDetailsS​​erviceImpl' 类型的合格 bean 可用:预期 至少 1 个符合自动装配候选资格的 bean。依赖 注释:{}

当我将SecurityConfiguration 类bean 添加到此测试时:

@MockBean
private JwtAuthenticationProvider jwtAuthenticationProvider;
@MockBean
private UserDetailsServiceImpl userDetailsService;
@MockBean
private DataSource dataSource;

测试正常运行,没有任何NoSuchBeanDefinitionException 异常。

这个解决方案对我来说还不够。有没有其他方法可以避免将安全 bean 放入每个集成测试中?

我尝试使用:

  • @Import({ErrorHandlerConfiguration.class, SecurityConfiguration.class})
  • @ContextConfiguration(classes = {SecurityConfiguration.class})

没有任何结果。

(为简洁起见,删除了方法主体和一些字符串)

// 编辑 附加的缺失类,注入到SecurityConfiguration

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
//method implementation
}

@Component
public class JwtAuthenticationProvider implements AuthenticationProvider {
//method implementation
}

【问题讨论】:

  • 也许这会有所帮助:stackoverflow.com/a/63508842/14072498
  • 感谢您的链接。但主要区别在于@SpringBootTest 运行整个 ApplicationContext(即带有持久层),我不需要集成测试来测试控制器响应。也许没有其他选择,我必须运行整个上下文。无论如何比小费。
  • 为什么SecurityConfiguration中的构造函数是空的?
  • @Toerktumlare 构造函数为简洁起见为空。参数被分配给类字段。我修好了。

标签: java spring spring-boot spring-security spring-test-mvc


【解决方案1】:
@WebMvcTest(
    value = SomeController.class,
    excludeAutoConfiguration = SecurityAutoConfiguration.class,
    excludeFilters = @ComponentScan.Filter(
            type = FilterType.ASSIGNABLE_TYPE,
            classes = WebSecurityConfigurer.class))
@AutoConfigureMockMvc(addFilters = false)
public class SomeControllerTest {

    @Autowired
    MockMvc mockMvc;
    
    ...
}

【讨论】:

  • 您使用excludeFilters@AutoConfigureMockMvc(addFilters = false) 的第一个示例有效!感谢您的提示。
【解决方案2】:

这是一个合格的猜测,但由于某种原因你没有发布缺少UserDetailsServiceImpl的课程。

如果您阅读有关 WebMvcTest 的文档,它会指出:

@WebMvcTest 自动配置 Spring MVC 基础结构并将扫描的 bean 限制为 @Controller@ControllerAdvice@JsonComponentConverterGenericConverterFilterHandlerInterceptorWebMvcConfigurer、和HandlerMethodArgumentResolver

使用@WebMvcTest 注释时,不会扫描常规的@Component@ConfigurationProperties bean。 @EnableConfigurationProperties 可用于包含 @ConfigurationProperties bean。

所以我猜你的 bean 没有因为这个原因被选中,这一切都在 docs 中说明。

但如前所述,这是一个猜测,因为出于某种原因,您没有发布缺少的代码供我们查看,并且还有一些未知数,例如空构造函数和其他空函数。

【讨论】:

  • 我添加了注入SecurityConfiguration的类。
猜你喜欢
  • 2015-08-12
  • 2013-01-11
  • 1970-01-01
  • 2012-06-15
  • 2014-02-01
  • 2012-05-10
  • 2012-10-02
  • 2013-04-19
  • 2013-08-29
相关资源
最近更新 更多