Spring Cloud (11): Service Gateway Zuul (filter) "Version Finchley" Posted in 2018-04-23 | updated on 2018-05-07 |
In the previous article we learned about the basic functionality of Spring Cloud Zuul as a gateway: Routing (Router). In this article, we will focus on another core feature of Spring Cloud Zuul: Filter.
The role of Filter
We have been able to implement the routing capabilities of the request, so our MicroServices application provides interfaces that can be accessed by the client through a unified API Gateway portal.
However, when each client user requests the interface provided by the MicroServices application, their access is often limited, and the system does not open all of the microservices interfaces to them. However, current service routing does not have the ability to restrict permissions, and all requests are forwarded unreservedly to the specific application and return the results.
The simplest and most brutal way to implement security checks and permissions control for client requests is to implement a filter or interceptor for each microservices application that verifies the signature and authentication permissions. However, this is not advisable, it will increase the future of system maintenance difficulty, because the same system of various check logic is roughly the same or similar, so that the implementation of similar verification logic code is scattered across the micro-services, redundant code appears we do not want to see. Therefore, it is better to take these check logic out of the way and build an independent authentication service. After the split, many developers will directly in the micro-service application by invoking the authentication service to achieve the verification, but this is only to solve the separation of the authentication logic, and did not in essence this part of the logic does not belong to the original micro-service application, redundant interceptors or filters will still exist.
For such a problem, it is better to perform these non-business checks by using the Gateway Service in front of you. Because the Gateway service joins, the external client accesses our system already has the unified entrance, since these checks are not related to the specific business, then does not have to complete the checksum filtering when the request arrives, but is not forwards after the filtering and causes the longer request delay. At the same time, by completing the checksum filtering in the gateway, the micro-service application can remove all kinds of complex filters and interceptors, which makes the interface development and testing complexity of the micro-service application be reduced correspondingly.
To enable validation of client requests in the API gateway, we will need to use another core feature of Spring Cloud Zuul: filters .
Zuul allows developers to implement blocking and filtering of requests by defining filters on the API gateway, which is a very simple way to implement them.
The life cycle of the Filter
The life cycle of Filter is 4, "PRE", "ROUTING", "POST" and "ERROR", the entire life cycle can be used to represent
Zuul Most of the functionality is implemented through filters, which correspond to the typical life cycle of the request.
- Pre: This filter is called before the request is routed. We can use this filter to authenticate, select the requested microservices in the cluster, log debug information, and so on.
- ROUTING: This filter routes requests to microservices. This filter is used to build requests sent to MicroServices and request microservices using the Apache HttpClient or Netfilx Ribbon.
- POST: This filter is executed after routing to the Micro service. This filter can be used to add standard HTTP headers for responses, collect statistics and metrics, send responses from microservices to clients, and so on.
- Error : executes the filter at the other stage when a fault occurs. In addition to the default filter type, Zuul allows us to create custom filter types. For example, we can customize a STATIC type of filter to generate a response directly in the Zuul, without forwarding the request to the backend micro-service.
Filter that is implemented by default in Zuul pre
type |
Order |
Filter | Filters
function |
Pre |
-3 |
servletdetectionfilter |
tags handling types of servlets |
-2 |
servlet30wrapperfilter |
wrapper httpservletrequest request |
pre |
-1 |
Formbodywrapperfilter |
Wrapper request Body |
Route |
1 |
debugfilter |
flag Debug Flag |
Route |
5 |
predecorationfilter |
Process request context for subsequent use |
Route |
ten |
ribbonroutingfilter |
serviceId Request Forwarding |
Route |
+ |
simplehostroutingfilter |
URL Request forwarding |
Route |
$ |
sendforwardfilter |
forward Request forwarding |
Post |
0 |
senderrorfilter |
handle request response with error |
Post |
+ |
sendresponsefilter |
Process A normal request response |
Disables the specified Filter
You can configure the filter to be disabled in APPLICATION.YML in the format zuul.<SimpleClassName>.<filterType>.disable=true
.
For example, to disable the org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter
set
Copy
1 2 3 4
|
Zuul: Sendresponsefilter: Post True
|
Custom Filter
We assume that there is a scenario where the service gateway is dealing with all external requests, and in order to avoid a security breach, we need to make certain restrictions on the request, such as having tokens in the request to keep the request going, and if the request is directly returned without token and given a hint.
First, customize a Filter, inherit the Zuulfilter abstract class, and verify in the run () method whether the parameter contains tokens, as follows:
Copy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21st 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
PublicClassTokenfilterExtendsZuulfilter {
/** * The type of filter, which determines which life cycle the filter executes in the request. * This is defined as the pre, and the delegate executes before the request is routed. * *@return */ @Override Public StringFilterType() { Return"Pre"; }
/** * Filter execution order, specified by number. * The higher the number, the lower the priority level. * *@return */ @Override PublicIntFilterorder() { Return0; }
/** * Determine if the filter needs to be executed. Here we directly return true, so the filter will take effect for all requests. * We can use this function to specify the effective range of the filter in practice. * *@return */ @Override PublicBooleanShouldfilter() { ReturnTrue }
/** * Specific logic of the filter * *@return */ @Override Public Objectrun () { RequestContext CTX = Requestcontext.getcurrentcontext (); HttpServletRequest request = Ctx.getrequest (); if (token = = null | | token.isempty ()) { Ctx.setsendzuulresponse (false); Ctx.setresponsestatuscode (401); Ctx.setresponsebody ( return null; } /span> |
In the filter code implemented above, we implement a custom filter by inheriting the ZuulFilter
abstract class and re-writing the following four methods. These four methods respectively define the following:
filterType()
: The type of filter that determines which life cycle the filter executes in the request. This is defined as a pre
representation that is executed before the request is routed.
filterOrder()
: The order in which the filters are executed. When a request has multiple filters in one phase, it needs to be executed sequentially based on the value returned by the method. By specifying the number, the higher the number, the lower the priority.
shouldFilter()
: Determines whether the filter needs to be executed. Here we return directly true
, so the filter will take effect for all requests. In practice we can use this function to specify the effective range of the filter.
run()
: The specific logic of the filter. Here we ctx.setSendZuulResponse(false)
can further optimize our return by making Zuul filter the request, not routing it, and then by ctx.setResponseStatusCode(401)
setting its return error code, for example, by ctx.setResponseBody(body)
editing the returned body content.
After implementing a custom filter, it does not take effect directly, and we also need to create a specific Bean for it to start the filter, for example, add the following in the application main class:
Copy
1 2 3 4 5 6 7 8 9 10 11 12 13
|
@EnableZuulProxy @SpringBootApplication public class apigatewayapplication { static void main ( String[] (args) { Springapplication.run (Apigatewayapplication.class, args); @Bean public tokenfilter tokenfilter () { return new Tokenfilter (); /span> |
After the api-gateway
service has completed the above transformation, we can restart it and initiate the following request to verify the filter defined above:
- Access HTTP://LOCALHOST:14000/CONSUMER/HELLO/WINDMT returns 401 errors and
token is empty
- Access Http://localhost:14000/consumer/hello/windmt?token=token correctly routed to
consumer
the /hello
interface, and returnsHello, windmt
We can define a number of business-agnostic general logic implementations to filter and intercept requests, such as signature checking, permission checking, request throttling, and so on, according to our needs.
Related reading
Spring Cloud (i): Overview of service governance Technologies
Spring Cloud (ii): Service Registration and Discovery Eureka
Spring Cloud (iii): service delivery and invocation Eureka
Spring Cloud (iv): Service-tolerant protection hystrix
Spring Cloud (v): Hystrix Monitor Panel
Spring Cloud (vi): Hystrix monitoring Data Aggregation Turbine
Spring Cloud (vii): Configuration Center (Git vs. dynamic refresh)
Spring Cloud (eight): Configuration Center (service and high availability)
Spring Cloud (ix): Configuration Center (message bus)
Spring Cloud (10): Service Gateway Zuul (routing)
Spring Cloud (11): Service Gateway Zuul (filter)
Spring Cloud (12): Distributed Link Tracking (Sleuth and Zipkin)
Sample code: GitHub
Reference
Spring Cloud-router and Filter:zuul
Springcloud (11): Service Gateway Zuul Advanced Chapter
Spring Cloud builds microservices architecture: Service Gateway (filter) "Version Dalston"
- this article Yibo
- This article link: https://windmt.com/2018/04/23/spring-cloud-11-zuul-filter/
- Copyright Notice: All articles in this blog are subject to the CC BY-NC-SA 4.0 license Agreement except for special statements. Reprint please specify the source!
Spring Cloud (11): Service Gateway Zuul (filter) "Version Finchley"