简体   繁体   English

如何在集成测试中使用 spring 安全性?

[英]How to use spring security in integration tests?

I have a following WebSecurityConfigurerAdapter implementation:我有以下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());
    }
}

This security works fine for normal running application.这种安全性适用于正常运行的应用程序。 But in tests - fails.但在测试中 - 失败了。 I have an integration test like:我有一个集成测试,例如:

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

    @MockBean
    private RegistrationService registrationService;

    @Test
    void shouldConfirmRegistration() {}
}

and after run, I get following error:运行后,我收到以下错误:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfiguration' defined in file [SecurityConfiguration.class]: Unsatisfied dependency expressed through constructor parameter 0;原因:org.springframework.beans.factory.UnsatisfiedDependencyException:创建文件[SecurityConfiguration.class]中定义的名称为“securityConfiguration”的bean时出错:通过构造函数参数0表示的不满足的依赖关系; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'UserDetailsServiceImpl' available: expected at least 1 bean which qualifies as autowire candidate.嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有“UserDetailsServiceImpl”类型的合格 bean 可用:预计至少有 1 个有资格作为自动装配候选者的 bean。 Dependency annotations: {}依赖注释:{}

When I add to this test SecurityConfiguration class beans:当我添加到此测试SecurityConfiguration class bean 中时:

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

tests runs normally, without any NoSuchBeanDefinitionException exceptions.测试正常运行,没有任何NoSuchBeanDefinitionException异常。

This solution isn't enough for me.这个解决方案对我来说还不够。 Is there any other way to avoid putting security beans to each integrtation tests?有没有其他方法可以避免将安全 bean 放入每个集成测试中?

I tried to use:我尝试使用:

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

without any results.没有任何结果。

(removed methods body and some strings for brevity) (为简洁起见,删除了方法主体和一些字符串)

// EDIT Attached missing classes, which are injected into SecurityConfiguration : // 编辑附加的缺失类,这些类被注入到SecurityConfiguration中:

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

@Component
public class JwtAuthenticationProvider implements AuthenticationProvider {
//method implementation
}
@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;
    
    ...
}

this is a qualified guess, but for some reason you have not posted the class that is missing UserDetailsServiceImpl .这是一个合格的猜测,但由于某种原因,您没有发布缺少UserDetailsServiceImpl erviceImpl 的 class 。

If you read the documentation about WebMvcTest it states:如果您阅读有关WebMvcTest的文档,它会指出:

@WebMvcTest auto-configures the Spring MVC infrastructure and limits scanned beans to @Controller , @ControllerAdvice , @JsonComponent , Converter , GenericConverter , Filter , HandlerInterceptor , WebMvcConfigurer , and HandlerMethodArgumentResolver . @WebMvcTest自动配置 Spring MVC 基础结构并将扫描的 bean 限制为@Controller@ControllerAdvice@JsonComponentConverterGenericConverterFilterHandlerInterceptorWebMvcConfigurerHandlerMethodArgumentResolver

Regular @Component and @ConfigurationProperties beans are not scanned when the @WebMvcTest annotation is used.使用@WebMvcTest注释时,不会扫描常规@Component@ConfigurationProperties bean。 @EnableConfigurationProperties can be used to include @ConfigurationProperties beans. @EnableConfigurationProperties可用于包含@ConfigurationProperties bean。

So im guessing your bean isn't picked up for this reason, its all stated in the docs .所以我猜你的豆子没有因为这个原因被捡起来,这一切都在文档中说明。

But as said, this is a guess because for some reason you have not posted the code that is missing for us to take a look at, and there are several unknows, as to the empty constructor, and other empty functions.但如前所述,这是一种猜测,因为由于某种原因,您没有发布缺少的代码供我们查看,并且还有一些未知数,例如空构造函数和其他空函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM