繁体   English   中英

无法自动将单个过滤器从Spring Security应用于MockMvc

[英]Apply selectively a single filter to MockMvc from Spring Security when it is not autowirable

我的WebSecurityConfigurerAdapter是使用http.csrf().csrfTokenRepository(csrfTokenRepository());

我想做一个仅激活CSRF过滤的集成测试,但是我遇到了一个问题:

  • CSRFTokenRepository未在上下文中公开
  • Spring似乎没有将CSRFilter作为bean暴露在上下文中

我想以以下方式进行测试:

   this.mockMvc = webAppContextSetup(super.webApplicationContext)
            .apply(springSecurity(CSRFFilter.class)) //This is just a showcase of that I pretend
            .alwaysDo(print())
            .build();

如何选择性地将单个过滤器(如CSRFFilter)应用到集成测试中,而不是通用的SecurityMockMvcConfigurers.springSecurity()?

请注意,此答案附有完整且有效的示例。

这种问题很有趣。 因为它如下

  1. 发现一个问题,该问题未在堆栈溢出问题中披露
  2. 有解决该问题的建议方案
  3. 提出的解决方案成为问题,但我们不知道这是最佳解决方案

因此,我不确定您是否应该在测试中修改应用程序上的筛选器链。 最终结果是您不是在测试应用程序,而是在测试永远不会投入生产的修改后的应用程序。

为了使疑惑的人受益,而提出的问题是最佳解决方案,这是可能的。 这是我做的

我创建了一个自定义过滤器 ,该过滤器在执行任何其他过滤器之前会返回500错误。

static class FiveHundredFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        response.setStatus(500);
        response.getWriter().write("TEST FILTER CHAIN");
    }
}

然后,我创建了一个BeanPostProcessor ,将该过滤器添加到我的所有过滤器链中。 您可以选择将其添加到此处的链。

static class SecurityFilterChainPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if ("springSecurityFilterChain".equals(beanName)) {
            FilterChainProxy fcp = (FilterChainProxy) bean;
            for (SecurityFilterChain fc : fcp.getFilterChains()) {
                fc.getFilters().add(0, new FiveHundredFilter());
            }
        }
        return bean;
    }
}

最后,我在应用程序上下文中将SecurityFilterChainPostProcessor作为bean公开

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(basePackages = "org/springframework/security/community/samples")
public static class SpringBootApplicationTestConfig {
    @Bean
    SecurityFilterChainPostProcessor securityFilterChainPostProcessor() {
        return new SecurityFilterChainPostProcessor();
    }
}

我相信这可以解决您的难题。

暂无
暂无

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

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