Spring会话认证策略的安全集成测试

Spring Security integration test for session authentication strategy

我有一个 Spring MVC + Spring 安全 Web 应用程序。 该应用程序在配置中设置了自定义会话身份验证策略

http.sessionManagement()
                .sessionAuthenticationStrategy( ... )

由于该策略包含复杂的逻辑,因此通过集成测试来测试其行为很重要。

当我们使用spring-security-test @WithMockUser 时,控制器方法在测试中被调用,但是我们的身份验证策略未被调用

在 Spring 安全测试中执行完整身份验证过程以确保会话身份验证策略确实被调用的正确方法是什么?

或者换句话说:如何调用整个 spring 安全过滤器链?

谢谢你的想法。

在您的集成测试中,提供一个 static WebSecurityConfigurerAdapter 它应该被拾取。

例如:

@EnableWebSecurity
static class CustomSessionAuthenticationStrategyConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .sessionManagement()
                .sessionAuthenticationStrategy(customSessionAuthenticationStrategy);
    }
}

更新:

这是 Spring 安全性 4.x 中的 MockMvc 测试。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class SessionAuthenticationStrategyTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mvc;

    @Before
    public void setup() {
        mvc = MockMvcBuilders
                .webAppContextSetup(context)
                .apply(springSecurity())
                .build();
    }

    @Test
    public void requestWhenCustomSessionAuthenticationStrategyProvidedThenCalled() throws Exception {
        this.mvc.perform(formLogin().user("user").password("password"));
        verify(CustomSessionAuthenticationStrategyConfig.customSessionAuthenticationStrategy)
                .onAuthentication(any(Authentication.class), any(HttpServletRequest.class), any(HttpServletResponse.class));
    }

    @EnableWebSecurity
    static class CustomSessionAuthenticationStrategyConfig extends WebSecurityConfigurerAdapter {
        static SessionAuthenticationStrategy customSessionAuthenticationStrategy = mock(SessionAuthenticationStrategy.class);

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                .formLogin()
                    .and()
                .sessionManagement()
                    .sessionAuthenticationStrategy(customSessionAuthenticationStrategy);
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth
                .inMemoryAuthentication()
                    .withUser("user").password("password").authorities("ROLE_USER");
        }
    }
}