Spring boot Spring WebFlux请求主体在测试中为空

Spring boot Spring WebFlux请求主体在测试中为空,spring-boot,spring-security,spring-webflux,Spring Boot,Spring Security,Spring Webflux,我们有一个库,它为我们的请求提供了一个自定义过滤器,我们使用它将请求的信息写入日志。我们以前只需要servlet支持,但现在需要添加webflux支持。我已经创建了一个新的WebFilter,它可以正常工作 然而,尝试测试这种新的过滤器一直很困难。我们依赖于日志的用户信息请求中的主体,但是在测试期间,它总是空的。我尝试了很多东西,包括下面的例子: 我的过滤器: package com.project.utils.security.request.logging.config.autoconfig

我们有一个库,它为我们的请求提供了一个自定义过滤器,我们使用它将请求的信息写入日志。我们以前只需要servlet支持,但现在需要添加webflux支持。我已经创建了一个新的WebFilter,它可以正常工作

然而,尝试测试这种新的过滤器一直很困难。我们依赖于日志的用户信息请求中的主体,但是在测试期间,它总是空的。我尝试了很多东西,包括下面的例子:

我的过滤器:

package com.project.utils.security.request.logging.config.autoconfig;

import com.project.utils.logging.LoggingUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

public class ReactiveRequestLoggingFilter implements WebFilter {
  private static final Logger logger = LoggerFactory.getLogger(ReactiveRequestLoggingFilter.class);

  @Override
  public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
    return serverWebExchange
        .getPrincipal()
        .flatMap(
            principal -> {
              LoggingUtil loggingUtil =
                  new LoggingUtil(serverWebExchange.getRequest(), principal.getName());
              loggingUtil.setEvent("Http Request");
              logger.info(loggingUtil.toString());
              return webFilterChain.filter(serverWebExchange);
            });
  }
}
我用于测试的控制器:

package com.project.utils.security.request.logging.config.testcontrollers;

import com.project.utils.security.request.logging.config.annotations.EnableReactiveRequestLogging;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/test")
@EnableReactiveRequestLogging
public class ReactiveTestController {
  @GetMapping
  Mono<ResponseEntity<String>> get() {
    return Mono.just(ResponseEntity.ok("GET"));
  }
}
package com.project.utils.security.request.logging.config.testcontrollers;
导入com.project.utils.security.request.logging.config.annotations.EnableReactiveRequestLogging;
导入org.springframework.http.ResponseEntity;
导入org.springframework.web.bind.annotation.GetMapping;
导入org.springframework.web.bind.annotation.RequestMapping;
导入org.springframework.web.bind.annotation.RestController;
导入reactor.core.publisher.Mono;
@RestController
@请求映射(“/test”)
@启用ReactiveRequestLogging
公共类反应测试控制器{
@GetMapping
monoget(){
返回Mono.just(ResponseEntity.ok(“GET”));
}
}
我们使用的是SpringBoot2.1,它使用SpringSecurity5.1。正如我所说,实际的功能是有效的,但我们需要为它编写测试,我不知道如何将主体引入请求中


谢谢

好的,从这个答案中找到了一个有效的解决方案:

我的期末考试是这样的:

package com.project.utils.security.request.logging.config.autoconfig;

import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.springSecurity;
import com.project.utils.security.request.logging.config.testcontrollers.ReactiveTestController;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {ReactiveTestController.class, ReactiveRequestLoggingFilter.class})
@WebFluxTest(controllers = {ReactiveTestController.class})
@WithMockUser(value = "Test User", username = "TestUser")
class ReactiveRequestLoggingFilterTest {
  @Autowired ReactiveTestController controller;
  @Autowired ReactiveRequestLoggingFilter filter;

  @Test
  void test() {
    WebTestClient client =
        WebTestClient.bindToController(controller)
            .webFilter(new SecurityContextServerWebExchangeWebFilter())
            .webFilter(filter)
            .apply(springSecurity())
            .build();
    client
        .get()
        .uri("/test")
        .exchange()
        .expectStatus()
        .isOk()
        .expectBody(String.class)
        .isEqualTo("GET");
  }
}


好的,从这个答案中找到了一个有效的解决方案:

我的期末考试是这样的:

package com.project.utils.security.request.logging.config.autoconfig;

import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.springSecurity;
import com.project.utils.security.request.logging.config.testcontrollers.ReactiveTestController;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {ReactiveTestController.class, ReactiveRequestLoggingFilter.class})
@WebFluxTest(controllers = {ReactiveTestController.class})
@WithMockUser(value = "Test User", username = "TestUser")
class ReactiveRequestLoggingFilterTest {
  @Autowired ReactiveTestController controller;
  @Autowired ReactiveRequestLoggingFilter filter;

  @Test
  void test() {
    WebTestClient client =
        WebTestClient.bindToController(controller)
            .webFilter(new SecurityContextServerWebExchangeWebFilter())
            .webFilter(filter)
            .apply(springSecurity())
            .build();
    client
        .get()
        .uri("/test")
        .exchange()
        .expectStatus()
        .isOk()
        .expectBody(String.class)
        .isEqualTo("GET");
  }
}


您需要通过身份验证才能访问/测试?否则,Spring Security不会应用于该特定端点,那么在向该端点发出请求时就没有主体的概念。我需要对其进行身份验证,因为筛选器依赖于主体的存在。您需要进行身份验证才能访问/测试吗?否则,Spring安全性不会应用于该特定端点,那么在向该端点发出请求时就没有主体的概念。我需要对其进行身份验证,因为过滤器依赖于主体的存在。