全局过滤器(默认对所有路由生效)
全局过滤器(认证)
@Component
public class MyAuthorizeGlobalFilter implements GlobalFilter, Ordered {
@Resource
private CustomProperties customProperties;
@Resource
private RedissonSingleService<String> redissonSingleServiceString;
@Override
public int getOrder() {
return GatewayFilterOrderEnum.MY_AUTHORIZE.getValue();
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest serverHttpRequest = exchange.getRequest();
ServerHttpResponse serverHttpResponse = exchange.getResponse();
String reqPath = serverHttpRequest.getURI().getPath();
List<String> whiteUrlList = customProperties.getSys().getWhiteUrlList();
PathMatcher pathMatcher = new AntPathMatcher();
for (String authIgnoreTemp : whiteUrlList) {
if (StrUtil.isEffective(authIgnoreTemp) && pathMatcher.match(authIgnoreTemp, reqPath)) {
LoggerUtil.info(MessageFormat.format("MyAuthorizeGlobalFilter 全局认证过滤器 ---- 地址无需登陆:{0}",reqPath));
return chain.filter(exchange);
}
}
LoggerUtil.info(MessageFormat.format("MyAuthorizeGlobalFilter 全局认证过滤器 ---- 地址需要登陆:{0}",reqPath));
LoggerUtil.info("");
String token = serverHttpRequest.getHeaders().getFirst(SysKeyEnum.TOKEN.getKey());
if (!StrUtil.isEffective(token)) {
return MonoResponseUtil.getVoidMono(serverHttpResponse, new BaseResult<String>().fail("TOKEN缺失"));
}
try {
BaseLoginUserInfo baseLoginUserInfo = JwtUtil.verifyJwtForHs256(token);
String versionKey = MessageFormat.format(SysKeyEnum.LOGIN_USER_VERSION.getKey(), SysKeyConstant.PROJECTNAME, baseLoginUserInfo.getUserAccount());
if (!redissonSingleServiceString.isExists(versionKey)) {
return MonoResponseUtil.getVoidMono(serverHttpResponse, new BaseResult<String>().fail(SysStateEnum.RESPONSE_STATUS_FALSE_TOKEN_TIMEOUT.getDescribe()));
} else {
String tokenVersion = redissonSingleServiceString.getKey(versionKey);
if (!baseLoginUserInfo.getVersion().equals(tokenVersion)) {
return MonoResponseUtil.getVoidMono(serverHttpResponse, new BaseResult<String>().fail(SysStateEnum.RESPONSE_STATUS_FALSE_TOKEN_EXISTS.getDescribe()));
}
}
Consumer<HttpHeaders> httpHeaders = httpHeader -> {
httpHeader.set(SysKeyEnum.USERINFO_ACCOUNT.getKey(), baseLoginUserInfo.getUserAccount());
httpHeader.set(SysKeyEnum.USERINFO_PHONE.getKey(), baseLoginUserInfo.getUserAccount());
httpHeader.remove(SysKeyEnum.TOKEN.getKey());
};
ServerHttpRequest serverHttpRequestMutable = serverHttpRequest.mutate().headers(httpHeaders).build();
ServerWebExchange serverWebExchangeMutable = exchange.mutate().request(serverHttpRequestMutable).build();
return chain.filter(serverWebExchangeMutable).then(Mono.fromRunnable(() -> {
LoggerUtil.info(MessageFormat.format("MyAuthorizeGlobalFilter 全局认证过滤器 ---- 全局后置过滤器回调逻辑:{0}",reqPath));
}));
} catch (Exception e) {
return MonoResponseUtil.getVoidMono(serverHttpResponse, new BaseResult<String>().fail(e.getMessage()));
}
}
}
网关过滤器(局部过滤器,需要为相关路由配置才可生效)
IP网关过滤器
1、创建IP网关过滤器
public class MyIpGatewayFilter implements GatewayFilter, Ordered {
private CustomProperties customProperties;
private MyIpGatewayFilterFactoryConfig myIpGatewayFilterFactoryConfig;
MyIpGatewayFilter(CustomProperties customProperties, MyIpGatewayFilterFactoryConfig myIpGatewayFilterFactoryConfig) {
this.customProperties = customProperties;
this.myIpGatewayFilterFactoryConfig = myIpGatewayFilterFactoryConfig;
}
@Override
public int getOrder() {
return GatewayFilterOrderEnum.MY_IP.getValue();
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
if ("*".equalsIgnoreCase(myIpGatewayFilterFactoryConfig.getWhiteIp())) {
return chain.filter(exchange);
} else {
ServerHttpRequest serverHttpRequest = exchange.getRequest();
ServerHttpResponse serverHttpResponse = exchange.getResponse();
String reqPath = serverHttpRequest.getURI().getPath();
String reqIp = Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress();
List<String> whiteIpList = customProperties.getSys().getWhiteIpList();
List<String> configIpList = Arrays.asList(myIpGatewayFilterFactoryConfig.getWhiteIp().split(","));
if (whiteIpList.contains(reqIp) || configIpList.contains(reqIp)) {
LoggerUtil.info(MessageFormat.format("MyIpGatewayFilter IP网关过滤器 ---- IP无需拦截:{0}", reqIp));
LoggerUtil.info("");
return chain.filter(exchange);
}
return MonoResponseUtil.getVoidMono(serverHttpResponse, new BaseResult<String>().fail("您还没有权限访问,请联系管理员"));
}
}
}
2、创建过滤器参数配置类
@Data
@NoArgsConstructor
public class MyIpGatewayFilterFactoryConfig {
private String whiteIp;
}
3、创建过滤器工厂
@Component
public class MyIpGatewayFilterFactory extends AbstractGatewayFilterFactory<MyIpGatewayFilterFactoryConfig> {
@Resource
private CustomProperties customProperties;
public MyIpGatewayFilterFactory() {
super(MyIpGatewayFilterFactoryConfig.class);
}
@Override
public List<String> shortcutFieldOrder() {
return Collections.singletonList("whiteIp");
}
@Override
public GatewayFilter apply(MyIpGatewayFilterFactoryConfig config) {
return new MyIpGatewayFilter(customProperties, config);
}
}
4、配置IP网关过滤器
# TODO 基于 【BFF-AUTH】 服务的路由配置
- id: BFF-AUTH-ROUTE
uri: lb://bffAuth
predicates:
- Path=/springCloudGateway/auth
请求参数网关过滤器
1、 创建请求参数网关过滤器
public class MyRequestParamsGatewayFilter implements GatewayFilter, Ordered {
private MyRequestParamsGatewayFilterFactoryConfig myRequestParamsGatewayFilterFactoryConfig;
public MyRequestParamsGatewayFilter(MyRequestParamsGatewayFilterFactoryConfig myRequestParamsGatewayFilterFactoryConfig) {
this.myRequestParamsGatewayFilterFactoryConfig = myRequestParamsGatewayFilterFactoryConfig;
}
@Override
public int getOrder() {
return GatewayFilterOrderEnum.MY_REQUEST_PARAMS.getValue();
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String schema = request.getURI().getScheme();
if ((!"http".equalsIgnoreCase(schema) && !"https".equalsIgnoreCase(schema))) {
return chain.filter(exchange);
}
String reqPath = request.getPath().toString();
String method = request.getMethodValue();
MediaType mediaType = exchange.getRequest().getHeaders().getContentType();
exchange.getAttributes().put("isDecrypt", myRequestParamsGatewayFilterFactoryConfig.getIsDecrypt());
if (SysKeyEnum.GET.getKey().equalsIgnoreCase(method)) {
MultiValueMap<String, String> queryParams = request.getQueryParams();
if (SysStateEnum.STATE_YES.getDescribe().equalsIgnoreCase(myRequestParamsGatewayFilterFactoryConfig.getIsDecrypt())) {
LoggerUtil.info("解密成功");
}
return chain.filter(exchange)
.then(Mono.fromRunnable(() -> {
if (SysStateEnum.STATE_YES.getDescribe().equalsIgnoreCase(myRequestParamsGatewayFilterFactoryConfig.getIsPrint())) {
LoggerUtil.info("");
LoggerUtil.info(MessageFormat.format("MyRequestParamsGatewayFilter 入参全局过滤器 ---- start [GET]:{0}", reqPath));
if (SysStateEnum.STATE_YES.getDescribe().equalsIgnoreCase(myRequestParamsGatewayFilterFactoryConfig.getIsDecrypt())) {
LoggerUtil.info(MessageFormat.format("入参解密前: {0}", JSONObject.toJSONString(queryParams)));
LoggerUtil.info(MessageFormat.format("入参解密后: {0}", JSONObject.toJSONString(queryParams)));
} else {
LoggerUtil.info(MessageFormat.format("入参: {0}", JSONObject.toJSONString(queryParams)));
}
LoggerUtil.info("MyRequestParamsGatewayFilter 入参全局过滤器 ---- end");
}
}));
} else if (SysKeyEnum.POST.getKey().equalsIgnoreCase(method) && MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)) {
ServerRequest serverRequest = ServerRequest.create(exchange, HandlerStrategies.withDefaults().messageReaders());
AtomicReference<JSONObject> bodyJsonObj = new AtomicReference<>(new JSONObject());
Mono<String> modifiedBody = serverRequest.bodyToMono(String.class).flatMap(body -> {
bodyJsonObj.set(JSON.parseObject(body));
if (SysStateEnum.STATE_YES.getDescribe().equalsIgnoreCase(myRequestParamsGatewayFilterFactoryConfig.getIsDecrypt())) {
LoggerUtil.info("解密成功");
}
return Mono.just(JSONObject.toJSONString(bodyJsonObj));
});
BodyInserter<Mono<String>, ReactiveHttpOutputMessage> bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);
HttpHeaders headers = new HttpHeaders();
headers.putAll(exchange.getRequest().getHeaders());
headers.remove(HttpHeaders.CONTENT_LENGTH);
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> {
ServerHttpRequestDecorator serverHttpRequestDecorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public HttpHeaders getHeaders() {
long contentLength = headers.getContentLength();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.putAll(super.getHeaders());
if (contentLength > 0) {
httpHeaders.setContentLength(contentLength);
} else {
httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
}
return httpHeaders;
}
@Override
public Flux<DataBuffer> getBody() {
Flux<DataBuffer> dataBufferFlux = outputMessage.getBody();
return dataBufferFlux;
}
};
ServerWebExchange serverWebExchangeMutable = exchange.mutate().request(serverHttpRequestDecorator).build();
return chain.filter(serverWebExchangeMutable)
.then(Mono.fromRunnable(() -> {
if (SysStateEnum.STATE_YES.getDescribe().equalsIgnoreCase(myRequestParamsGatewayFilterFactoryConfig.getIsPrint())) {
LoggerUtil.info("");
LoggerUtil.info(MessageFormat.format("MyRequestParamsGatewayFilter ---- start [POST]:{0}", reqPath));
if (SysStateEnum.STATE_YES.getDescribe().equalsIgnoreCase(myRequestParamsGatewayFilterFactoryConfig.getIsDecrypt())) {
LoggerUtil.info(MessageFormat.format("请求入参解密前: {0}", bodyJsonObj.get().toJSONString()));
LoggerUtil.info(MessageFormat.format("请求入参解密后: {0}", bodyJsonObj.get().toJSONString()));
} else {
LoggerUtil.info(MessageFormat.format("请求入参: {0}", bodyJsonObj.get().toJSONString()));
}
LoggerUtil.info("MyRequestParamsGatewayFilter ---- end");
LoggerUtil.info("");
}
}));
}));
} else {
return chain.filter(exchange);
}
}
}
2、创建过滤器参数配置类
@Data
@NoArgsConstructor
public class MyRequestParamsGatewayFilterFactoryConfig {
private String isPrint;
private String isDecrypt;
}
3、创建过滤器工厂
@Component
public class MyRequestParamsGatewayFilterFactory extends AbstractGatewayFilterFactory<MyRequestParamsGatewayFilterFactoryConfig> {
public MyRequestParamsGatewayFilterFactory() {
super(MyRequestParamsGatewayFilterFactoryConfig.class);
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("isPrint","isDecrypt");
}
@Override
public GatewayFilter apply(MyRequestParamsGatewayFilterFactoryConfig config) {
return new MyRequestParamsGatewayFilter(config);
}
}
4、配置IP网关过滤器
# TODO 基于 【BFF-AUTH】 服务的路由配置
- id: BFF-AUTH-ROUTE
uri: lb://bffAuth
predicates:
- Path=/springCloudGateway/auth