使用 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,我创建了一个测试代码如下。 (addUser
和 signin
是扩展函数。)
@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
。使用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
还有。
我在 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,我创建了一个测试代码如下。 (addUser
和 signin
是扩展函数。)
@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
。使用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
还有。