问题现象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Component
public class ShiroFilter implements GlobalFilter, Ordered {
AuthFeign authFeign;

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
String token = request.getHeaders().getFirst("token");
String requestUrl = exchange.getRequest().getURI().getRawPath();

// OpenFeign
authFeign = SpringUtils.getBean(AuthFeign.class);
boolean permitted = authFeign.isPermitted(requestUrl,token);

if(!permitted){
return endResponse(response, new Result(401,"未授权"));
}
return chain.filter(exchange);
}
}

有一个GateWay过滤器,拦截所有请求,调用认证服务,判断是否有请求路径的权限

但是会引发一个问题

java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-3

解决方法

参考方法: Spring Cloud Gateway 调用Feign异步问题_浮生的博客-CSDN博客

写的很详细,可以去看看

根据网上查询的资料,GateWay基于WebFlux实现,WebFlux是异步的,我们写了一个同步调用方法,这样就引起了线程阻塞

所以我们只需要同步转异步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Component
public class ShiroFilter implements GlobalFilter, Ordered {
AuthFeign authFeign;

ExecutorService executorService = Executors.newFixedThreadPool(1);

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
String token = request.getHeaders().getFirst("token");
String requestUrl = exchange.getRequest().getURI().getRawPath();

// OpenFeign
authFeign = SpringUtils.getBean(AuthFeign.class);
// WebFlux异步调用,同步会报错
boolean permitted = true;
Future<Boolean> future = executorService.submit(() ->authFeign.isPermitted(requestUrl,token));

try {
permitted = future.get();
System.out.println(permitted);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
if(!permitted){
return endResponse(response, new Result(401,"未授权"));
}
return chain.filter(exchange);
}
}