Netflix Zuul - 块请求路由

问题描述:

通过Zuul,我可以轻松定义在请求转发到特定服务之前或之后激活的自定义过滤器。Netflix Zuul - 块请求路由

有没有办法阻止请求在“预先”过滤级别转发,并立即发送响应给客户端? 我知道类似的东西可以用“静态”过滤器来实现,但是我需要根据请求来决定(基于请求本身中是否存在某些参数/头文件)。

我找到了解决方案,只需要在我的“pre”自定义过滤器的run()方法中添加context.setSendZuulResponse(false);

其他过滤器仍将被调用,但请求不会被路由到目标。

我使用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

下面是我如何使用zuul过滤器来检查例子获得授权的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等标题。最好自己设置它们,以便客户端浏览器等知道如何解析响应主体。