搜索了網上的一些資料,發現各有各的解釋,且解釋的不太清楚。
查看了zuul的源碼後得出結論:
- 倆個配置都是用來過濾header的,只不過sensitiveHeaders不配置時,會有三個默認過濾的header頭。
- 不做任何配置的情況下,header會全部往下轉發,除了Cookie、Set-Cookie、Authorization
- 無論是配置ignoredHeaders和sensitiveHeaders都會在轉發時過濾掉
- ignoredHeaders只有zuul.ignoredHeaders的全局配置
- sensitiveHeaders有zuul.sensitiveHeaders的全局配置和zuul.routes.xxxrouteId.sensitiveHeaders的私有配置
相關源碼如下:
public class ZuulProperties {
...
//sensitiveHeaders的默認三個過濾header配置
private Set<String> sensitiveHeaders = new LinkedHashSet<>(
Arrays.asList("Cookie", "Set-Cookie", "Authorization"));
...
}
sensitiveHeaders配置會在請求經過PreDecorationFilter過濾器時合併到ProxyRequestHelper對象的ignoredHeaders中:
//PreDecorationFilter的122行
if (!route.isCustomSensitiveHeaders()) {
this.proxyRequestHelper
.addIgnoredHeaders(this.properties.getSensitiveHeaders().toArray(new String[0]));
}
else {
this.proxyRequestHelper.addIgnoredHeaders(route.getSensitiveHeaders().toArray(new String[0]));
}
最終往下轉發的header是在SimpleHostRoutingFilter或RibbonRoutingFilter中生成:
//RibbonRoutingFilter的129行
MultiValueMap<String, String> headers = this.helper
.buildZuulRequestHeaders(request);
//SimpleHostRoutingFilter的201行
MultiValueMap<String, String> headers = this.helper
.buildZuulRequestHeaders(request);
可以看到最終都是通過ProxyRequestHelper的buildZuulRequestHeaders生成:
public MultiValueMap<String, String> buildZuulRequestHeaders(
HttpServletRequest request) {
RequestContext context = RequestContext.getCurrentContext();
MultiValueMap<String, String> headers = new HttpHeaders();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
//通過isIncludedHeader方法過濾
if (isIncludedHeader(name)) {
Enumeration<String> values = request.getHeaders(name);
while (values.hasMoreElements()) {
String value = values.nextElement();
headers.add(name, value);
}
}
}
}
Map<String, String> zuulRequestHeaders = context.getZuulRequestHeaders();
for (String header : zuulRequestHeaders.keySet()) {
if (isIncludedHeader(header)){
headers.set(header, zuulRequestHeaders.get(header));
}
}
if(!headers.containsKey(HttpHeaders.ACCEPT_ENCODING)) {
headers.set(HttpHeaders.ACCEPT_ENCODING, "gzip");
}
return headers;
}
isIncludedHeader方法:
public boolean isIncludedHeader(String headerName) {
String name = headerName.toLowerCase();
RequestContext ctx = RequestContext.getCurrentContext();
if (ctx.containsKey(IGNORED_HEADERS)) {
Object object = ctx.get(IGNORED_HEADERS);
//在IGNORED_HEADERS中的header會被過濾掉
if (object instanceof Collection && ((Collection<?>) object).contains(name)) {
return false;
}
}
switch (name) {
case "host":
if(addHostHeader) {
return true;
}
case "connection":
case "content-length":
case "server":
case "transfer-encoding":
case "x-application-context":
return false;
default:
return true;
}
}