问题描述
我有一个使用Zuul的网关服务。我只允许通过此网关来自特定host/origin/url
的入站请求。我可以在网关服务的yaml文件(特别是 zuul 字段下)中设置一个属性来完成此操作吗?我的网关服务yaml看起来像这样:
description: the gateway service of the year
version: 1.0.0
server:
port: 5555
spring:
application:
name: gateway-srv
main:
allow-bean-deFinition-overriding: true
homeUrl: http://localhost:8080
zuul:
routes:
foo:
authorization:
password: baz
username: bar
path: /foo/**
sensitiveHeaders: Cookie,Set-Cookie
url: ${homeUrl}/lc
解决方法
您可以包含Zuul预过滤器来管理这种情况,类似于:
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;
import static java.util.Optional.ofNullable;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.DEBUG_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
@Log4j2
@Component
public class RequestFilter extends ZuulFilter {
@Override
public String filterType() {
return PRE_TYPE;
}
@Override
public int filterOrder() {
return DEBUG_FILTER_ORDER;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
log.info(getRequestInformation(ctx.getRequest()));
return getRequestInformation(ctx.getRequest())
.filter(rInfo -> !allowedRequest(rInfo))
.map(rInfo -> {
// You can adapt it,usign for example,a Json as response
ctx.setResponseBody("Request not authorized");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
return ctx;
})
.orElse( null);
}
private boolean allowedRequest(RequestInformation requestInformation) {
// Include here what you need to verify
// Modify with the suitable result
return false;
}
private Optional<RequestInformation> getRequestInformation(HttpServletRequest httpRequest) {
return ofNullable(httpRequest)
.map(req -> {
String hostAndPort = req.getHeader("host");
return new RequestInformation(
httpRequest.getRequestURI(),ofNullable(hostAndPort).map(hp -> hp.substring(0,hp.indexOf(":"))).orElse(null),ofNullable(hostAndPort).map(hp -> Integer.valueOf(hp.substring(hp.indexOf(":")+1))).orElse(null));
});
}
// Dummy class to include the information you need to check
class RequestInformation {
private String url;
private String host;
private Integer port;
public RequestInformation(String url,String host,Integer port) {
this.url = url;
this.host = host;
this.port = port;
}
public String getUrl() {
return url;
}
public String getHost() {
return host;
}
public Integer getPort() {
return port;
}
@Override
public String toString() {
return "RequestInformation{" +
"url='" + url + '\'' +
",host='" + host + '\'' +
",port=" + port +
'}';
}
}
}
现在,如果您基于Zuul运行网关服务,则应该在日志中看到:
而且,如果您保持allowedRequest
返回一个false
值: