如何忽略客户端(原始请求)的标头,例如user-id
,但是在过滤器中,我从oauth设置了用户ID,并由addZuulRequestHeader("user-id", "value")
设置了用户ID,然后是微服务将使用。
我使用ignore-headers
,那么即使我通过zuul过滤器设置了标头,它也会忽略所有内容。如何仅忽略客户端请求中的标头,却允许zuul添加它?
答案 0 :(得分:0)
您可以实现以下过滤器:
@Component
public class MyHeaderFilter extends ZuulFilter {
@Override
public String filterType() {
return PRE_TYPE;
}
@Override
public int filterOrder() {
return PRE_DECORATION_FILTER_ORDER - 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
final RequestContext context = RequestContext.getCurrentContext();
context.addZuulRequestHeader("user-id", "whateverValue");
return null;
}
}
您可以如上所述替换标头值。
答案 1 :(得分:0)
我亲自研究了一下,得出的结论是,唯一好的方法是包装HttpServletRequest,以使禁止的标头不会在HttpServletRequest::getHeaderNames
调用中返回。 ProxyRequestHelper
对原始请求标头和使用RequestContext.getCurrentContext().addZuulRequestHeader(headerName, headerValue)
设置的标头都使用了忽略的标头集,因此,您不能只使用忽略的标头集。
您可以在各种路由过滤器中覆盖ProxyRequestHelper
或执行以下操作:创建包装器(确保forbiddenHeaders
的值被修剪和小写):
public class ForbiddenHeadersRequestWrapperEnforcer extends HttpServletRequestWrapper
{
private Set<String> forbiddenHeaders;
public ForbiddenHeadersRequestWrapperEnforcer(HttpServletRequest request, Set<String> forbiddenHeaders)
{
super(request);
this.forbiddenHeaders = forbiddenHeaders;
}
@Override
public Enumeration<String> getHeaderNames()
{
Set<String> headerNames = enumerationToLowercaseSet(super.getHeaderNames());
headerNames.removeAll(forbiddenHeaders);
return Collections.enumeration(headerNames);
}
private Set<String> enumerationToLowercaseSet(Enumeration<String> enumeration)
{
Set<String> set = new HashSet<>();
while (enumeration.hasMoreElements()) {
set.add(enumeration.nextElement().toLowerCase());
}
return set;
}
}
一个简单的属性类:
@Component
@ConfigurationProperties("zuul")
public class ForbiddenHeadersProperties
{
private List<String> forbiddenHeaders;
public List<String> getForbiddenHeaders()
{
return forbiddenHeaders;
}
public void setForbiddenHeaders(List<String> forbiddenHeaders)
{
this.forbiddenHeaders = forbiddenHeaders;
}
}
并在Zuul过滤器中使用该包装器:
@Component
public class ForbiddenHeaderEnforcerRouteFilter extends ZuulFilter
{
private Set<String> forbiddenHeaders;
public ForbiddenHeaderEnforcerRouteFilter(ForbiddenHeadersProperties forbiddenHeadersConfiguration)
{
this.forbiddenHeaders = forbiddenHeadersConfiguration.getForbiddenHeaders()
.stream()
.map(String::toLowerCase)
.map(String::trim)
.collect(Collectors.toSet());
}
@Override
public int filterOrder()
{
return Integer.MIN_VALUE;
}
@Override
public String filterType()
{
return FilterConstants.ROUTE_TYPE;
}
@Override
public boolean shouldFilter()
{
return true;
}
@Override
public Object run() throws ZuulException
{
RequestContext currentContext = RequestContext.getCurrentContext();
currentContext.setRequest(new ForbiddenHeadersRequestWrapperEnforcer(currentContext.getRequest(),
forbiddenHeaders));
return null;
}
}
这样,您可以使用RequestContext.getCurrentContext().addZuulRequestHeader(headerName, headerValue)
设置标头,这些标头将发送到后端,但不会发送到原始请求中的标头。