|
|
@@ -2,63 +2,82 @@ package cc.mrbird.febs.gateway.filter;
|
|
|
|
|
|
import cc.mrbird.febs.common.entity.FebsConstant;
|
|
|
import cc.mrbird.febs.common.entity.FebsResponse;
|
|
|
-import cc.mrbird.febs.common.utils.FebsUtil;
|
|
|
import cc.mrbird.febs.gateway.properties.FebsGatewayProperties;
|
|
|
-import com.netflix.zuul.ZuulFilter;
|
|
|
-import com.netflix.zuul.context.RequestContext;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.ArrayUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
|
|
|
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
|
|
+import org.springframework.cloud.gateway.filter.GlobalFilter;
|
|
|
+import org.springframework.cloud.gateway.route.Route;
|
|
|
+import org.springframework.core.annotation.Order;
|
|
|
+import org.springframework.core.io.buffer.DataBuffer;
|
|
|
+import org.springframework.http.HttpHeaders;
|
|
|
+import org.springframework.http.HttpStatus;
|
|
|
import org.springframework.http.MediaType;
|
|
|
+import org.springframework.http.server.reactive.ServerHttpRequest;
|
|
|
+import org.springframework.http.server.reactive.ServerHttpResponse;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
import org.springframework.util.AntPathMatcher;
|
|
|
import org.springframework.util.Base64Utils;
|
|
|
+import org.springframework.web.server.ServerWebExchange;
|
|
|
+import reactor.core.publisher.Mono;
|
|
|
|
|
|
-import javax.servlet.http.HttpServletRequest;
|
|
|
-import javax.servlet.http.HttpServletResponse;
|
|
|
-import java.io.IOException;
|
|
|
+import java.net.URI;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.LinkedHashSet;
|
|
|
+
|
|
|
+import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.*;
|
|
|
|
|
|
/**
|
|
|
- * 请求前置过滤器
|
|
|
- *
|
|
|
* @author MrBird
|
|
|
*/
|
|
|
@Slf4j
|
|
|
@Component
|
|
|
-public class FebsGatewayRequestFilter extends ZuulFilter {
|
|
|
+@Order(0)
|
|
|
+public class FebsGatewayRequestFilter implements GlobalFilter {
|
|
|
|
|
|
@Autowired
|
|
|
private FebsGatewayProperties properties;
|
|
|
-
|
|
|
private AntPathMatcher pathMatcher = new AntPathMatcher();
|
|
|
|
|
|
@Override
|
|
|
- public String filterType() {
|
|
|
- return FilterConstants.PRE_TYPE;
|
|
|
- }
|
|
|
+ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
|
|
+ ServerHttpRequest request = exchange.getRequest();
|
|
|
+ ServerHttpResponse response = exchange.getResponse();
|
|
|
|
|
|
- @Override
|
|
|
- public int filterOrder() {
|
|
|
- return 6;
|
|
|
- }
|
|
|
+ Mono<Void> checkForbidUriResult = checkForbidUri(request, response);
|
|
|
+ if (checkForbidUriResult != null) {
|
|
|
+ return checkForbidUriResult;
|
|
|
+ }
|
|
|
|
|
|
- @Override
|
|
|
- public boolean shouldFilter() {
|
|
|
- return true;
|
|
|
+ printLog(exchange);
|
|
|
+
|
|
|
+ byte[] token = Base64Utils.encode((FebsConstant.GATEWAY_TOKEN_VALUE).getBytes());
|
|
|
+ ServerHttpRequest build = request.mutate().header(FebsConstant.GATEWAY_TOKEN_HEADER, new String(token)).build();
|
|
|
+ ServerWebExchange newExchange = exchange.mutate().request(build).build();
|
|
|
+ return chain.filter(newExchange);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public Object run() {
|
|
|
- RequestContext ctx = RequestContext.getCurrentContext();
|
|
|
- String serviceId = (String) ctx.get(FilterConstants.SERVICE_ID_KEY);
|
|
|
- HttpServletRequest request = ctx.getRequest();
|
|
|
- String host = request.getRemoteHost();
|
|
|
- String method = request.getMethod();
|
|
|
- String uri = request.getRequestURI();
|
|
|
- log.info("请求URI:{},HTTP Method:{},请求IP:{},ServerId:{}", uri, method, host, serviceId);
|
|
|
+ private void printLog(ServerWebExchange exchange) {
|
|
|
+ URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
|
|
|
+ Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
|
|
|
+ LinkedHashSet<URI> uris = exchange.getAttribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR);
|
|
|
+ URI originUri = null;
|
|
|
+ if (uris != null) {
|
|
|
+ originUri = uris.stream().findFirst().orElse(null);
|
|
|
+ }
|
|
|
+ if (url != null && route != null && originUri != null) {
|
|
|
+ log.info("转发请求:{}://{}{} --> 目标服务:{},目标地址:{}://{}{},转发时间:{}",
|
|
|
+ originUri.getScheme(), originUri.getAuthority(), originUri.getPath(),
|
|
|
+ route.getId(), url.getScheme(), url.getAuthority(), url.getPath(), LocalDateTime.now()
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ private Mono<Void> checkForbidUri(ServerHttpRequest request, ServerHttpResponse response) {
|
|
|
+ String uri = request.getPath().toString();
|
|
|
boolean shouldForward = true;
|
|
|
String forbidRequestUri = properties.getForbidRequestUri();
|
|
|
String[] forbidRequestUris = StringUtils.splitByWholeSeparatorPreserveAllTokens(forbidRequestUri, ",");
|
|
|
@@ -70,23 +89,16 @@ public class FebsGatewayRequestFilter extends ZuulFilter {
|
|
|
}
|
|
|
}
|
|
|
if (!shouldForward) {
|
|
|
- HttpServletResponse response = ctx.getResponse();
|
|
|
FebsResponse febsResponse = new FebsResponse().message("该URI不允许外部访问");
|
|
|
- try {
|
|
|
- FebsUtil.makeResponse(
|
|
|
- response, MediaType.APPLICATION_JSON_UTF8_VALUE,
|
|
|
- HttpServletResponse.SC_FORBIDDEN, febsResponse
|
|
|
- );
|
|
|
- ctx.setSendZuulResponse(false);
|
|
|
- ctx.setResponse(response);
|
|
|
- } catch (IOException e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- return null;
|
|
|
+ return makeResponse(response, febsResponse);
|
|
|
}
|
|
|
-
|
|
|
- byte[] token = Base64Utils.encode((FebsConstant.ZUUL_TOKEN_VALUE).getBytes());
|
|
|
- ctx.addZuulRequestHeader(FebsConstant.ZUUL_TOKEN_HEADER, new String(token));
|
|
|
return null;
|
|
|
}
|
|
|
+
|
|
|
+ private Mono<Void> makeResponse(ServerHttpResponse response, FebsResponse febsResponse) {
|
|
|
+ response.setStatusCode(HttpStatus.FORBIDDEN);
|
|
|
+ response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
|
|
|
+ DataBuffer dataBuffer = response.bufferFactory().wrap(JSONObject.toJSONString(febsResponse).getBytes());
|
|
|
+ return response.writeWith(Mono.just(dataBuffer));
|
|
|
+ }
|
|
|
}
|