Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Netflix Zuul - block request routing

Tags:

netflix-zuul

With Zuul I can easily define custom filters that are activated before or after the request is forwarded to the specific service.

Is there a way to block requests from being forwarded at a "pre" filter level, and send immediately the response to the client? I know something similar is doable with "static" filters, but I need to decide per request (based on the presence of certain parameters/headers in the request itself).

like image 790
Rohi Avatar asked May 15 '16 20:05

Rohi


People also ask

How does ZUUL routing work?

Routing is an integral part of a microservice architecture. For example, / may be mapped to your web application, /api/users is mapped to the user service and /api/shop is mapped to the shop service. Zuul is a JVM-based router and server-side load balancer from Netflix.

What is dynamic routing in ZUUL?

The Netflix Zuul service provides dynamic routing. Using Zuul in your app enables your services to use the information from the Eureka service directory to reach other services. Because both Eureka and Zuul are Java applications they can be implemented with Spring Boot, part of the Spring Framework for Java.

When a circuit for a given route in ZUUL is tripped you can provide a?

9.12 Providing Hystrix Fallbacks For Routes When a circuit for a given route in Zuul is tripped you can provide a fallback response by creating a bean of type ZuulFallbackProvider .

What is filter order in ZUUL?

There are four types of standard filters in Zuul: pre for pre-routing filtering, route for routing to an origin, post for post-routing filters, and error for error handling. Zuul also supports a static type for static responses. Any filter type can be created or added and run by calling the method runFilters(type).


3 Answers

Here is an example of how I use zuul-filter to check for an API-key being authorized. If not, I send a 401 response to the client.

 @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;
    }

Note that if the client's API key is not authorized, all other filters will still be run, but the request will still fail due to ctx.setSendZuulResponse(false). When failing a response, it will by default be empty - that is, there is no headers such as Content-Type etc. It is a good idea to set them yourself so a client's browser etc. knows how to parse the response body.

like image 54
Kent Munthe Caspersen Avatar answered Jan 03 '23 23:01

Kent Munthe Caspersen


I use a pre filter to check the authentication of the request, and if the request dose not authorized, then I return 401 and do not call the back end service any more. I do it in run() function like this:

    RequestContext ctx = getCurrentContext();
    // do something to check the authentication
    if(auth failed){
      ctx.unset();
      ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
    }

ctx.unset() tell the context to stop this request, and ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value()); set the http code to 401

like image 21
Bruce Avatar answered Jan 04 '23 01:01

Bruce


I found the solution, just needed to add context.setSendZuulResponse(false); in the run() method of my "pre" custom filter.

Other filters will still be called, but request won't be routed to destination.

like image 26
Rohi Avatar answered Jan 03 '23 23:01

Rohi