【发布时间】:2021-03-03 03:15:37
【问题描述】:
我们有一个库,它为我们的请求提供了一个自定义过滤器,我们用它来将有关请求的信息写入我们的日志。我们以前只需要 servlet 支持,但现在需要添加 webflux 支持。我创建了一个新的 WebFilter,它按预期工作。
但是,尝试测试这个新过滤器很困难。我们在日志的用户信息请求中依赖于主体,但在测试期间,它始终为空。我尝试了很多东西,包括以下示例:https://docs.spring.io/spring-security/site/docs/5.1.0.RELEASE/reference/html/test-webflux.html
我的过滤器:
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.autoconfig;
import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.mockUser;
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.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = {ReactiveTestController.class})
class ReactiveRequestLoggingFilterTest {
@Autowired ReactiveTestController controller;
ReactiveRequestLoggingFilter filter = new ReactiveRequestLoggingFilter();
@Test
void test() {
WebTestClient client =
WebTestClient.bindToController(controller)
.webFilter(filter)
.apply(springSecurity())
.configureClient()
.build()
.mutateWith(mockUser("User"));
client
.get()
.uri("/test")
.exchange()
.expectStatus()
.isOk()
.expectBody(String.class)
.isEqualTo("GET");
}
}
我用于测试的控制器:
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"));
}
}
我们使用的是 Spring Boot 2.1,它使用 Spring Security 5.1。就像我说的,实际的功能是有效的,但是我们需要为它编写测试,我不知道如何让委托人进入请求。
谢谢!
【问题讨论】:
-
而您需要通过身份验证才能访问/test?否则,Spring Security 不会应用于该特定端点,那么在向该端点发出请求时就没有主体的概念。
-
我需要对其进行身份验证,因为过滤器依赖于存在的主体。
标签: spring-boot spring-security spring-webflux