当网关服务器受csrf保护且请求内容类型为application/x-www-form-urlencoded时,spring网关服务器失败

vd2z7a6w  于 2021-07-13  发布在  Java
关注(0)|答案(0)|浏览(377)

当网关服务器受csrf保护且请求内容类型为application/x-www-form-urlencoded时,spring网关服务器无法从upsteam服务器获得响应

有两个简单的服务器。

第一个是网关服务器。

这是唯一的进口网关和安全。

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-security</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.cloud</groupId>
  7. <artifactId>spring-cloud-starter-gateway</artifactId>
  8. </dependency>

就像这样的安全配置。它们非常简单。所以我把它们写在同一个班上

  1. @SpringBootApplication
  2. public class GatewayApplication {
  3. public static void main(String[] args) {
  4. SpringApplication.run(GatewayApplication.class, args);
  5. }
  6. @Bean
  7. public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
  8. http.authorizeExchange().anyExchange().permitAll();
  9. http.csrf().csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse());
  10. return http.build();
  11. }
  12. /**
  13. * add csrf cookie response on every response
  14. * @return
  15. */
  16. @Bean
  17. public WebFilter addCsrfTokenFilter() {
  18. return (exchange, next) -> Mono.just(exchange)
  19. .flatMap(ex -> ex.<Mono<CsrfToken>>getAttribute(CsrfToken.class.getName()))
  20. .doOnNext(ex -> {
  21. })
  22. .then(next.filter(exchange));
  23. }
  24. }

网关路由

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: test
  6. uri: http://localhost:8888
  7. predicates:
  8. - Path=/test/**
  9. filters:
  10. - StripPrefix=1

第二个是上游服务器

它是一个简单的web服务器

  1. @SpringBootApplication
  2. @RestController
  3. public class UpstreamApplication {
  4. @PostMapping("/test")
  5. public String postData(Dto dto) {
  6. return "post success";
  7. }
  8. public static void main(String[] args) {
  9. SpringApplication.run(UpstreamApplication.class, args);
  10. }
  11. }

dto类有两个属性a和b

  1. public class Dto {
  2. private String a;
  3. private String b;
  4. public String getA() {
  5. return a;
  6. }
  7. public void setA(String a) {
  8. this.a = a;
  9. }
  10. public String getB() {
  11. return b;
  12. }
  13. public void setB(String b) {
  14. this.b = b;
  15. }
  16. }

我在8888端口配置服务器

  1. server:
  2. port: 8888

然后,我用 Postman 来测试他们。第一次,我没有csrf值。

  1. curl --location --request POST 'http://localhost:8080/test/test' \
  2. --header 'Content-Type: application/x-www-form-urlencoded' \
  3. --data-urlencode 'a=1' \
  4. --data-urlencode 'b=2'

服务器响应无效csrf令牌异常。然后我从cookie值中得到csrf令牌值。然后我用csrf头发送请求。

  1. curl --location --request POST 'http://localhost:8080/test/test' \
  2. --header 'X-XSRF-TOKEN: f8db31f3-8be6-4103-8e15-5ef4594a08f0' \
  3. --header 'Content-Type: application/x-www-form-urlencoded' \
  4. --header 'Cookie: XSRF-TOKEN=f8db31f3-8be6-4103-8e15-5ef4594a08f0' \
  5. --data-urlencode 'a=1' \
  6. --data-urlencode 'b=2'

客户端等待响应超过3分钟,但未完成。
我测试的其他内容类型,他们完成正常。
如果上游服务器的函数params为空或客户端请求params为空。它可以完成。
测试项目在这里https://github.com/ldwqh0/spring_gateway_csrf_bug

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题