HTTPS/SSL AWS ELB 背后的 Zuul
Zuul behind an AWS ELB over HTTPS/SSL
我有一个 AWS Elastic Load Balancer
,其中包含我的域的证书,它终止了 SSL
流量。 ELB
在 https
端口上有一个侦听器并将其作为 http
转发到 Zuul
。
当我使用 Spring Boot HATEOAS
时,Zuul 将用正确的地址替换链接,但用 http
而不是 https
:
"_links": {
"self": {
"href": "http://my.domain.com:80/rest/foo/bar"
}
}
但我想要的是:
"_links": {
"self": {
"href": "https://my.domain.com/rest/foo/bar"
}
}
生成此响应的请求是通过 https
发出的
因为 Zuul
在 ELB 后面,我猜它不知道它应该通过 https 接收流量。
有没有办法告诉 Zuul
将链接替换为 https
,即使它通过 http
接收未加密的流量?
我想另一种方法是使用自签名证书将 Zuul
与 https
一起部署,但如果可以的话,我宁愿避免这种复杂情况。
根据 Zuul 团队的建议,可以通过添加 pre
Zuul 过滤器来解决此问题,该过滤器将在 PreDecorationFilter
(顺序 5)之后应用:
new ZuulFilter() {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 6; //PreDecorationFilter=5 + 1
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
log.info(String.format("Before filter ['%s': '%s', '%s': '%s']",
ZuulHeaders.X_FORWARDED_PROTO.toLowerCase(),
ctx.getZuulRequestHeaders().get(ZuulHeaders.X_FORWARDED_PROTO.toLowerCase()),
"X-Forwarded-Port",
ctx.getZuulRequestHeaders().get("x-forwarded-port")));
final String originalXForwardedProto = ctx.getRequest().getHeader(ZuulHeaders.X_FORWARDED_PROTO.toLowerCase());
final String originalXForwardedPort = ctx.getRequest().getHeader("x-forwarded-port");
if (!StringUtils.isEmpty(originalXForwardedProto)) {
ctx.addZuulRequestHeader(ZuulHeaders.X_FORWARDED_PROTO.toLowerCase(), originalXForwardedProto);
}
if (!StringUtils.isEmpty(originalXForwardedPort)) {
ctx.addZuulRequestHeader("x-forwarded-port", originalXForwardedPort);
}
log.info(String.format("After filter ['%s': '%s', '%s': '%s']",
ZuulHeaders.X_FORWARDED_PROTO.toLowerCase(),
ctx.getZuulRequestHeaders().get(ZuulHeaders.X_FORWARDED_PROTO.toLowerCase()),
"X-Forwarded-Port",
ctx.getZuulRequestHeaders().get("x-forwarded-port")));
return null;
}
};
}
我有一个 AWS Elastic Load Balancer
,其中包含我的域的证书,它终止了 SSL
流量。 ELB
在 https
端口上有一个侦听器并将其作为 http
转发到 Zuul
。
当我使用 Spring Boot HATEOAS
时,Zuul 将用正确的地址替换链接,但用 http
而不是 https
:
"_links": {
"self": {
"href": "http://my.domain.com:80/rest/foo/bar"
}
}
但我想要的是:
"_links": {
"self": {
"href": "https://my.domain.com/rest/foo/bar"
}
}
生成此响应的请求是通过 https
因为 Zuul
在 ELB 后面,我猜它不知道它应该通过 https 接收流量。
有没有办法告诉 Zuul
将链接替换为 https
,即使它通过 http
接收未加密的流量?
我想另一种方法是使用自签名证书将 Zuul
与 https
一起部署,但如果可以的话,我宁愿避免这种复杂情况。
根据 Zuul 团队的建议,可以通过添加 pre
Zuul 过滤器来解决此问题,该过滤器将在 PreDecorationFilter
(顺序 5)之后应用:
new ZuulFilter() {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 6; //PreDecorationFilter=5 + 1
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
log.info(String.format("Before filter ['%s': '%s', '%s': '%s']",
ZuulHeaders.X_FORWARDED_PROTO.toLowerCase(),
ctx.getZuulRequestHeaders().get(ZuulHeaders.X_FORWARDED_PROTO.toLowerCase()),
"X-Forwarded-Port",
ctx.getZuulRequestHeaders().get("x-forwarded-port")));
final String originalXForwardedProto = ctx.getRequest().getHeader(ZuulHeaders.X_FORWARDED_PROTO.toLowerCase());
final String originalXForwardedPort = ctx.getRequest().getHeader("x-forwarded-port");
if (!StringUtils.isEmpty(originalXForwardedProto)) {
ctx.addZuulRequestHeader(ZuulHeaders.X_FORWARDED_PROTO.toLowerCase(), originalXForwardedProto);
}
if (!StringUtils.isEmpty(originalXForwardedPort)) {
ctx.addZuulRequestHeader("x-forwarded-port", originalXForwardedPort);
}
log.info(String.format("After filter ['%s': '%s', '%s': '%s']",
ZuulHeaders.X_FORWARDED_PROTO.toLowerCase(),
ctx.getZuulRequestHeaders().get(ZuulHeaders.X_FORWARDED_PROTO.toLowerCase()),
"X-Forwarded-Port",
ctx.getZuulRequestHeaders().get("x-forwarded-port")));
return null;
}
};
}