Spring boot Spring WebFlux请求主体在测试中为空
我们有一个库,它为我们的请求提供了一个自定义过滤器,我们使用它将请求的信息写入日志。我们以前只需要servlet支持,但现在需要添加webflux支持。我已经创建了一个新的WebFilter,它可以正常工作 然而,尝试测试这种新的过滤器一直很困难。我们依赖于日志的用户信息请求中的主体,但是在测试期间,它总是空的。我尝试了很多东西,包括下面的例子: 我的过滤器: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
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安全性不会应用于该特定端点,那么在向该端点发出请求时就没有主体的概念。我需要对其进行身份验证,因为过滤器依赖于主体的存在。