【发布时间】:2016-09-11 14:54:11
【问题描述】:
使用 Zuul,我可以轻松定义在请求转发到特定服务之前或之后激活的自定义过滤器。
有没有办法阻止请求在“预”过滤级别转发,并立即将响应发送给客户端? 我知道使用“静态”过滤器可以进行类似的操作,但我需要根据请求来决定(基于请求本身中是否存在某些参数/标头)。
【问题讨论】:
标签: netflix-zuul
使用 Zuul,我可以轻松定义在请求转发到特定服务之前或之后激活的自定义过滤器。
有没有办法阻止请求在“预”过滤级别转发,并立即将响应发送给客户端? 我知道使用“静态”过滤器可以进行类似的操作,但我需要根据请求来决定(基于请求本身中是否存在某些参数/标头)。
【问题讨论】:
标签: netflix-zuul
这是我如何使用 zuul-filter 来检查 API 密钥是否被授权的示例。如果没有,我会向客户端发送 401 响应。
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String apiKey = request.getHeader("X-API-KEY");
if (!isAuthorized(apiKey)){
// blocks the request
ctx.setSendZuulResponse(false);
// response to client
ctx.setResponseBody("API key not authorized");
ctx.getResponse().setHeader("Content-Type", "text/plain;charset=UTF-8");
ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
return null;
}
请注意,如果客户端的 API 密钥未授权,所有其他过滤器仍将运行,但请求仍会因ctx.setSendZuulResponse(false) 而失败。
当响应失败时,默认情况下它将为空 - 也就是说,没有诸如 Content-Type 之类的标头。最好自己设置它们,以便客户端的浏览器等知道如何解析响应正文。
【讨论】:
sendZuulResponse 是否已经被伪造 - 我猜你的目标是不考虑更多过滤器并立即向客户端返回响应。
我使用pre 过滤器检查请求的身份验证,如果请求未授权,则返回401 并且不再调用后端服务。我在run() 函数中这样做:
RequestContext ctx = getCurrentContext();
// do something to check the authentication
if(auth failed){
ctx.unset();
ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
ctx.unset()告诉上下文停止这个请求,ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());设置http代码为401
【讨论】:
我找到了解决办法,只需要添加context.setSendZuulResponse(false);
在我的“pre”自定义过滤器的 run() 方法中。
仍会调用其他过滤器,但不会将请求路由到目的地。
【讨论】: