zuul的ignoredHeaders和sensitiveHeaders配置詳解

搜索了網上的一些資料,發現各有各的解釋,且解釋的不太清楚。
查看了zuul的源碼後得出結論:

  1. 倆個配置都是用來過濾header的,只不過sensitiveHeaders不配置時,會有三個默認過濾的header頭。
  2. 不做任何配置的情況下,header會全部往下轉發,除了Cookie、Set-Cookie、Authorization
  3. 無論是配置ignoredHeaders和sensitiveHeaders都會在轉發時過濾掉
  4. ignoredHeaders只有zuul.ignoredHeaders的全局配置
  5. 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;
		}
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章