使用WebTestClientAutoConfiguration时是否可以指定webSessionManager?

时间:2018-07-26 04:32:05

标签: kotlin spring-test spring-webflux

我正在Spring Boot 2.0.3.RELEASE中使用Webflux创建REST API。通过该实现,我如下自定义并使用 webSessionManager

@EnableWebFluxSecurity
@Configuration
class SecurityConfiguration {
    @Bean
    fun webSessionManager(): WebSessionManager {
        return DefaultWebSessionManager().apply {
            sessionIdResolver = HeaderWebSessionIdResolver().apply {
                headerName = "X-Sample"
            }
            sessionStore = InMemoryWebSessionStore()
        }
    }

    // ...
}

为了测试REST API,我创建了一个测试代码,如下所示。 (addUsersignin是扩展功能。)

@RunWith(SpringRunner::class)
@SpringBootTest
@AutoConfigureWebTestClient
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class UserTests {
    @Autowired
    private lateinit var client: WebTestClient

    @Test
    fun testGetUserInfo() {
        client.addUser(defaultUser)
        val sessionKey = client.signin(defaultUser)

        client.get().uri(userPath)
                .header("X-Sample", sessionKey)
                .exchange()
                .expectStatus().isOk
                .expectBody()
                .jsonInStrict("""
                {
                  "user": {
                    "mail_address": "user@example.com"
                  }
                }
                """.trimIndent())
    }

    // ...
}

测试失败。经授权拒绝。但是,如果我启动服务器并从curl运行它,它将成功进行授权。

调查原因后,结果发现org.springframework.test.web.reactive.server.AbstractMockServerSpec webSessionManager 设置为DefaultWebSessionManager。使用默认值,而不使用我自定义的 webSessionManager 。因此,它无法获取会话ID。

如何更改AbstractMockServerSpec的webSessionManager?

此外,我认为最好执行以下实现,您认为呢?

abstract class AbstractMockServerSpec<B extends WebTestClient.MockServerSpec<B>>
        implements WebTestClient.MockServerSpec<B> {

    // ...

    private WebSessionManager sessionManager = null;

    // ...

    @Override
    public WebTestClient.Builder configureClient() {
        WebHttpHandlerBuilder builder = initHttpHandlerBuilder();
        builder.filters(theFilters -> theFilters.addAll(0, this.filters));
        if (this.sessionManager != null) {
            builder.sessionManager(this.sessionManager);
        }
        this.configurers.forEach(configurer -> configurer.beforeServerCreated(builder));
        return new DefaultWebTestClientBuilder(builder);
    }

    // ...
}

1 个答案:

答案 0 :(得分:0)

Spring Framework的AbstractMockServerSpec提供了一种自定义WebSessionManager的方法。

感谢打开SPR-17094,将使用该票证解决此问题-AbstractMockServerSpec已经在寻找应用程序上下文中的基础结构位,这也应检查WebSessionManager