Netflix Zuul - 阻止请求路由

时间:2016-05-15 20:31:38

标签: netflix-zuul

使用Zuul,我可以轻松定义在请求转发到特定服务之前或之后激活的自定义过滤器。

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

3 个答案:

答案 0 :(得分:4)

以下是我如何使用zuul-filter检查授权的API密钥的示例。如果没有,我会向客户发送401回复。

func createTabBarItems(_ containers: [CGRect]) {

    var index = 0
    for item in tabBarItems {
        let container = containers[index]

        let customTabBarItem = CustomTabBarItem(frame: container)
        customTabBarItem.setup(item) // HERE I call my setup() method of my Tab Bar Item

        self.addSubview(customTabBarItem)
        customTabBarItems.append(customTabBarItem)

        let button = UIButton(frame: CGRect(x: 0, y: 0, width: container.width, height: container.height))
        button.addTarget(self, action: #selector(CustomTabBar.barItemTapped(_:)), for: UIControlEvents.touchUpInside)

        customTabBarItem.addSubview(button)
        tabBarButtons.append(button)

        index += 1
    }
}

请注意,如果客户端的API密钥未获得授权,则仍会运行所有其他过滤器,但由于 @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; } ,请求仍会失败。 当响应失败时,它默认为空 - 也就是说,没有诸如ctx.setSendZuulResponse(false)之类的标题等。最好自己设置它们,以便客户端的浏览器等知道如何解析响应体

答案 1 :(得分:3)

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

答案 2 :(得分:2)

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

仍会调用其他过滤器,但请求不会路由到目的地。