过滤器

1.FoundFilter(UserCredentialFilter) 用户凭证管控过滤器

@Slf4j
@Component
public class FoundFilter extends AbstractGatewayFilterFactory<FilterConfig> implements Ordered{
    public FoundFilter(){super(FilterConfig.class)}
   
    public GatewayFilter apply(FilterConfig config){
       return (exchange,chain)->{
             //如何关闭用户凭证,则放行
             if (!bizConfig.getSecurity().isUserCredentials()){
             
                 return chain.filter(exchange);
            }

             ServerHttpRequest request = exchange.getRequest();
             String token = request.getHeaders().getFirst("Authorization");
             String thirdFlag =  request.getHeaders().getFirst("isThird");
             Map<String,String> param = httpKit.toRemoteHeaderMap(token, thirdFlag);
             
            //从云网API调用
          List<RemoteCookieCtrl> cookieConfigs = null;
        try{
          cookieConfigs = remoteUserCredentialsService.getCredentials(param);
        }catch(Exception e){
           log.error("远程获取用户凭证管控请求错误:{}",e.getMessage());
           return chain.filter(exchange);
         }

            //列表为空,不校验放行
           if(CollectionUtil.isEmpty(cookieConfigs)){
                return chain.filter(exchange);
            }
          
            Map<String,HttpCookie> cookies = request.getCookies().toSingleValueMap();
             
            for (Map.Entry<String,HttpCookie> cookie: cookies.entrySet()){
                for( RemoteCookieCtrl cookieConfig: cookieConfigs) {
                   if  (cookie.getValue().getName().equals(cookieConfig.getCookieName())   && cookie.getValue().getValue().contains(cookieConfig.getCookieValue())){
                       // 存在匹配的,就放行
                        return chain.filter(exchange);
                      }
                }

           }
             SysUser user = null;
            saveLog(request,user);
            Response response = new Response(302,"未包含指定标识",null);
           return httpKit.response(exchange,response);

         };

   }
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public void saveLog(ServerHttpRequest request,SysUser user){

String currentTime = sdf.format(now());
String username = "-";
if(!StringUtils.isEmpty(user.getUserName())){
username =
user.getUserName();
}
String realIp = httpKit.findXRealIp(request);
RemoteSysLog sysLog = new RemoteSysLog();
sysLog.setCreateTime(currentTime);
sysLog.setRemoteAddr(realIp);
sysLog.setRequestUri(request.getURI().getPath());
sysLog.setMethod(request.getMethod().name());
//异步执行
executeService.submit(()->{
logService.save(sysLog);
}));
  }

}

 

2. HttpUtil http工具类

@Component
public class HttpUtil {
    public Map<String,String> toRemoteHeaderMap(String token,String thirdFlag){
           Map<String,String> param = new HashMap();
           if (!StringUtils.isEmpty(token)){
              param .put("Authorization",token);
             }
          if (!StringUtils.isEmpty(thirdFlag)){
              param.put("isThird",thirdFlag);
           }

         return param;

   }

  public string execute(String url,Map<String,String> headerMap,String method,String body) throws Exception{
      CloseableHttpClient httpClient = HttpClients.createDefault();
      RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000)
              .setSocketTimeout(30000);
              .build();
        HttpRequestBase httpRequest;
       if ("GET".equalsIgnoreCase(method)){
          httpRequest = new HttpGet(url);
       }else if ("POST".equalsIgnoreCase(method)){
          httpRequest = new HttpPost(url);
          if (!StringUtils.isEmpty(body) ){
              StringEntity entity = new StringEntity(body, "UTF-8");
              entity.setContentEncoding("UTF-8");
              entity.setContentType("application/json");
((HttpPost)httpRequest).setEntity(entity); 
          }
       } else {
          throw new IllegalArgumentException("Unsupported HTTP method:"+ method);
     }
     httpRequest.setConfig(requestConfig);
    if (!CollectionUtils.isEmpty(headerMap)){
        for (Map.Entry<String,String> entry: headerMap.entrySet()){
           httpRequest.setHeader(entry.getKey(),entry.getValue());
        }
    }
     CloseableHttpResponse response = httpClient.execute(httpRequest);
    try{ 
          int responseCode = response.getstatusLine().getStatusCode();
         if (responseCode = 200){
            return EntityUtils.toString(response.getEntity());
         } else{
            throw new IOException("Http request failed!,response="+EntityUtils.toString(response.getEntity()))
         }
    }finally{
        response.close();
    }
   
}
  //获得请求响应的body
  public String getBody(String url,Map<String,String> headerMap) throws Exception {
    
   return execute(url,headerMap,"GET",null);

}
  public String postBody(String url,Map<String,String> headerMap.String body) throws Exception {
    
   return execute(url,headerMap,"POST",body);

}
//响应
public Mono<Void> response(ServerWebExchange exchange,Response r){
ServerHttpResponse response = exchange.getResponse();
//客户端无法获取接口支持的请求方法
response.getHeaders().remove("Allow");
//浏览器会拦截跨域请求,触发跨域报错
response.getHeaders().remove("Access-Control-Allow-Origin");
response.setStatusCode(HttpStatus.valueOf(r.getCode()));
return response.writeWith(Mono.just(response.bufferFactory.wrap(("{\"code\":"+r.getCode()+",\"message\":\""+r.getMessage()+"\"}").getBytes())));

}

private String[] IP_HEADER_CANDIDATES = {
"X-Forwarded-For",
"Proxy-Client-IP",
"WL-Proxy-Client-IP",
"HTTP_X_FORWARDED_FOR",
"HTTP_X_FORWARDED",
"HTTP_X_CLUSTER_CLIENT_IP",
"HTTP_CLIENT_IP",
"HTTP_FORWARDED_FOR",
"HTTP_FORWARDED",
"HTTP_VIA",
"X-Real-IP"
};
//获取客户端真实ip
public String findXRealIp(ServerHttpRequest request){
//优先从常见的代理头中查找
for(String header: IP_HEADER_CANDIDATES){
List<String> headerValues = request.getHeaders().get(header);
if (!CollectionUtils.isEmpty(headerValues)){
               String ip = headerValues.get(0);
if (!StringUtils.isEmpty(ip) && !"unknown".equalsIgnoreCase(ip) && ip.contains(",")){
//处理x-forward-ip多值情况
ip = ip.split(",")[0].trim();
}
             retunn ip;
}
  }
//如果所有头都没有,则从远程地址获取
InetSocketAddress remoteAddress = request.getRemoteAddress();
if (remoteAddress != null)
{
return
remoteAddress.getAddress().getHostAddress();
   }
//如果都获取不到,返回一个默认值
return "unknown";

}
}
    

 3.CacheBodyFilter 请求体缓存过滤器

@Slf4j
@Component
public class CacheBodyFilter extends AbstactGatewayFilterFactory<FilterConfig> implements Ordered {
public CacheBodyFilter(){
super(FilterConfig.class);
}
String contentType = "application/json,application/x-www-form-urlencoded";
List<String> allowedContentType = Arrays.asList(contentType.split(","));
  public GatewayFilter apply(FilterConfig config){
return (exchange,chain) -> {
if (!bizConfig.getSecurity().isTamperMode()){
return chain.filter(exchange);
}
ServerHttpRequest request = exchange.getRequest();
String contentType = request.getHeaders().getFirst("Content-Type");
if (contentType != null && allowedContentType.contains(contentType)){
return DataBufferUtils.join(exchange.getRequest().getBody())
.flatMap(dataBuffer->{
if (dataBuffer.readableByteCount()>config.getMaxBodySize()){
exchange.getResponse().setStatusCode(HttpStatus.PAYLOAD_TOO_LARGE);
DataBufferUtils.release(dataBuffer);
return exchange.getResponse().setComplete();
}
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
DataBufferUtils.release(dataBuffer);

String body = new String(bytes,StandardCharsets.UTF_8);
//将body缓存到exchange属性中,供后续使用
exchange.getAttributes().put("cachedRequestBody",body);
return chain.filter(buildNewExchange(exchange,body));
});

}
//处理multipart/form-data请求
         if (contentType!= null && contentType.contains("multipart/form-data")){
return exchange.getMultipartData()
.flatMap(multipartData->{
if (multipartData == null || multipartData.isEmpty()){
return chain.filter(exchange);
}
// 创建最终的结果map
Map<String,Object> resultMap = new HashMap<>();
//处理文件部分
List<Map<String,Object>> fileList = new ArrayList<>();
return Flux.fromIterable(multipartData.entrySet())
.flatMap(entry -> {
String key = entry.getKey();
List<Part> parts = entry.getValue();
return Flux.fromIterable(parts)
.flatMap(part -> {
if(part instanceof FilePart){
//处理文件
FilePart filePart = (FilePart)part;
Map<String,Object> fileInfo = new HashMap<>();
                                             fileInfo.put("fileName",filePart.fileName());
fileInfo.put("contentType",filePart.headers().getContentType()!=null ? filePart.headers().getContentType().toString():"application/octet-stream");
//处理文件内容计算sha56
return filePart.content().reduce(new ByteArrayOutputStream(),(outputStream,dataBuffer) ->{
try{
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
outputStream.write(bytes);
DataBufferUtils.release(dataBuffer);
}catch(IOException e){
throw new RuntimeException(e);
}
return outputStream;
})
.map(outputStream -> {
try{
String sha256 = DigestUtil.sha256Hex(outputStream.toByteArray());
fileInfo.put("file",sha256);
}catch(Exception e){
throw new RuntimeException(e);
}
fileList.add(fileInfo);
return fileInfo;
});
}else if (part instanceof FormFieldPart){
//处理表单字段
FormFieldPart formField = (FormFieldPart)part;
resultMap.put(key,formField.value());
return Mono.just(formField);
}else {
return Mono.just(part);
}
});
}).collectList()
.doOnNext(ignored -> {
//将文件列表放入结果map
if (!fileList.isEmpty()){
resultMap.put("file",fileList);
}
}).then(Mono.fromRunnable(()->{
//将完整的结果缓存到exchange属性中
if (!resultMap.isEmpty()){
exchange.getAttributes().put("cachedMultipartFiles",resultMap);
}
}))
.then(chain.filter(exchange));

});

}
         return chain.filter(exchange);
};
}

//构建新的请求体
public ServerWebExchange buildNewExchange(ServerWebExchange exchange,String body){
//3 重新构建请求体
bytes[] newBytes = body.getBytes(StandardCharsets.UTF_8);
DataBuffer newDataBuffer = exchange.getResponse().bufferFactory().wrap(newBytes);
// 使用ServerHttpRequestDecorator 包装请求
ServerHttpRequest decoratedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) {
public Flux<DataBuffer> getBody{ return Flux.just(newDataBuffer);}
};
//4.创建新的ServerWebExchange
return exchange.mutate()
.request(decoratedRequest)
.build();


}

}

 4. CsrfFilter CSRF过滤器

@Slf4j

 

posted @ 2026-08-04 18:06  技术虫  阅读(5)  评论(0)    收藏  举报