如何在@WebFluxTest 中禁用 oauth2 客户端注册?

How to disable oauth2 client registration in @WebFluxTest?

已配置 oauth2:

security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: ${keycloak.server-url}/realms/${keycloak.realm}
      client:
        provider:
          keycloak:
            issuer-uri: ${keycloak.server-url}/realms/${keycloak.realm}
            user-name-attribute: email
        registration:
          keycloak:
            client-id: ${keycloak.client-id}
            client-secret: ${keycloak.client-secret}
            scope: openid

我想知道如何为控制器 运行 @WebFluxTest 而不必 运行 实际的 keycloak 服务器。以下测试 运行 很好,当我有本地 keycloak 服务器 运行ning:

@WebFluxTest(TaskController::class)
class TaskControllerTest {

  @Autowired
  private lateinit var client: WebTestClient

  @MockkBean
  private lateinit var taskService: TaskServiceImpl

  @Test
  @WithMockUser(roles = ["user"])
  fun getByIds() {
    val ids = setOf<Long>(1, 2)
    every { taskService.getByIds(ids, any()) } returns flowOf(
      TaskWithRating(
        Task(
          id = 1,
          title = "title",
          description = "desc"
        ),
        Rating(0, 0),
      )
    )
    client
      .get()
      .uri { uriBuilder ->
        uriBuilder
          .path("/tasks/byIds")
          .queryParam("ids", ids)
          .build()
      }
      .exchange()
      .expectStatus().isOk
      .expectBody()
      .jsonPath("$.length()").isEqualTo(1)
      .jsonPath("$.1.task.id").isEqualTo(1)
  }
}

当我停止本地 keycloak 服务器时,测试失败,因为 spring 试图在启动期间读取 oauth2 配置,同时创建 ApplicationContext:

Failed to load ApplicationContext
...
Factory method 'clientRegistrationRepository' threw exception; nested exception is java.lang.IllegalArgumentException: Unable to resolve Configuration with the provided Issuer of "https://keycloak.local.com/auth/realms/myrealm"
...
Caused by: org.springframework.web.client.ResourceAccessException: I/O error on GET request for "https://keycloak.local.com/auth/realms/myrealm/.well-known/openid-configuration": Connection refused; nested exception is java.net.ConnectException: Connection refused
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:784)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:669)
    at org.springframework.security.oauth2.client.registration.ClientRegistrations.lambda$oidc[=12=](ClientRegistrations.java:156)
    at org.springframework.security.oauth2.client.registration.ClientRegistrations.getBuilder(ClientRegistrations.java:209)
    ... 175 more
Caused by: java.net.ConnectException: Connection refused

测试用不着,反正用户是被mock了。所以我想在 @WebFluxTest 中禁用 auth2 配置,但我不知道这是如何以及是否是一种有效的方法?

我试过了。

@WebFluxTest(
  controllers = [TaskController::class],
  excludeAutoConfiguration = [ReactiveSecurityAutoConfiguration::class],
)

还有这个

@WebFluxTest(
  controllers = [TaskController::class],
  excludeAutoConfiguration = [ReactiveOAuth2ClientAutoConfiguration::class],
)

但是错误还是一样

事实证明我走对了路。必须禁用 oauth2 客户端和资源服务器自动配置。这有效:

@WebFluxTest(
  controllers = [TaskController::class],
  excludeAutoConfiguration = [
    ReactiveOAuth2ClientAutoConfiguration::class,
    ReactiveOAuth2ResourceServerAutoConfiguration::class,
  ],
)

请注意,这会绕过可能禁用的功能,因此,例如,需要在测试客户端上进行 csrf() 更改:

client
  .mutateWith(SecurityMockServerConfigurers.csrf()) 

另一种方法是使用 @Import(TestSecurityConfiguration::class) 为安全设置配置测试配置。