当网关服务器受csrf保护且请求内容类型为application/x-www-form-urlencoded时,spring网关服务器无法从upsteam服务器获得响应
有两个简单的服务器。
第一个是网关服务器。
这是唯一的进口网关和安全。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
就像这样的安全配置。它们非常简单。所以我把它们写在同一个班上
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http.authorizeExchange().anyExchange().permitAll();
http.csrf().csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse());
return http.build();
}
/**
* add csrf cookie response on every response
* @return
*/
@Bean
public WebFilter addCsrfTokenFilter() {
return (exchange, next) -> Mono.just(exchange)
.flatMap(ex -> ex.<Mono<CsrfToken>>getAttribute(CsrfToken.class.getName()))
.doOnNext(ex -> {
})
.then(next.filter(exchange));
}
}
网关路由
spring:
cloud:
gateway:
routes:
- id: test
uri: http://localhost:8888
predicates:
- Path=/test/**
filters:
- StripPrefix=1
第二个是上游服务器
它是一个简单的web服务器
@SpringBootApplication
@RestController
public class UpstreamApplication {
@PostMapping("/test")
public String postData(Dto dto) {
return "post success";
}
public static void main(String[] args) {
SpringApplication.run(UpstreamApplication.class, args);
}
}
dto类有两个属性a和b
public class Dto {
private String a;
private String b;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
}
我在8888端口配置服务器
server:
port: 8888
然后,我用 Postman 来测试他们。第一次,我没有csrf值。
curl --location --request POST 'http://localhost:8080/test/test' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'a=1' \
--data-urlencode 'b=2'
服务器响应无效csrf令牌异常。然后我从cookie值中得到csrf令牌值。然后我用csrf头发送请求。
curl --location --request POST 'http://localhost:8080/test/test' \
--header 'X-XSRF-TOKEN: f8db31f3-8be6-4103-8e15-5ef4594a08f0' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: XSRF-TOKEN=f8db31f3-8be6-4103-8e15-5ef4594a08f0' \
--data-urlencode 'a=1' \
--data-urlencode 'b=2'
客户端等待响应超过3分钟,但未完成。
我测试的其他内容类型,他们完成正常。
如果上游服务器的函数params为空或客户端请求params为空。它可以完成。
测试项目在这里https://github.com/ldwqh0/spring_gateway_csrf_bug
暂无答案!
目前还没有任何答案,快来回答吧!