使用 WebTestClientAutoConfiguration 时有没有办法指定 webSessionManager?

Is there a way to specify webSessionManager when using WebTestClientAutoConfiguration?

我在 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.AbstractMockServerSpecwebSessionManager设置为DefaultWebSessionManager。使用default,不是我自定义的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);
    }

    // ...
}

Spring 框架的 AbstractMockServerSpec 已经提供了一种自定义 WebSessionManager 的方法。

感谢您打开 SPR-17094,这个问题将通过该票得到解决 - AbstractMockServerSpec 已经在查看基础设施位的应用程序上下文,这应该检查 WebSessionManager还有。