Примените выборочно один фильтр к MockMvc из Spring Security, когда он не является автомойкой - PullRequest
0 голосов
/ 11 января 2019

Мой WebSecurityConfigurerAdapter определен с http.csrf().csrfTokenRepository(csrfTokenRepository());

Я хочу сделать интеграционный тест, который активирует только фильтрацию CSRF, но у меня возникла проблема:

  • CSRFTokenRepository не предоставляется в контексте
  • CSRFilter, по-видимому, не представляется в контексте как bean-компонент Spring

Я бы хотел провести тестирование следующим образом:

   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 Ответ

0 голосов
/ 11 января 2019

Обратите внимание, что этот ответ сопровождается полным и рабочим образцом.

Такие вопросы интересны. Потому что это выглядит следующим образом

  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 как компонент в контексте моего приложения

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

Я считаю, что это должно решить вашу дилемму.

...