Blog Original: http://blog.csdn.net/liuchuanhong1/article/details/62236793
In the front we built the gateway using Zuul http://blog.csdn.net/liuchuanhong1/article/details/59056278
Regarding the function of the gateway, here does not repeat again, our focus today is Zuul filter. With filter, we can implement security controls, for example, only clients with a user name and password in the request parameters can access the server's resources. So how to implement filter?
To implement filter, you need the following steps:
1, inherit the Zuulfilter class, in order to verify the properties of filter, we create 3 filter here
Filter by user name
Package Com.chhliu.springcloud.zuul; Import Javax.servlet.http.HttpServletRequest; Import Com.netflix.zuul.ZuulFilter; Import Com.netflix.zuul.context.RequestContext; Public classAccessusernamefilter extends Zuulfilter {@Override PublicObject Run () {RequestContext CTX=Requestcontext.getcurrentcontext (); HttpServletRequest Request=ctx.getrequest (); System. out. println (String.Format ("%s Accessusernamefilter request to%s", Request.getmethod (), Request.getrequesturl (). toString ()); String username= Request.getparameter ("username");//get the requested parameters if(NULL! = Username && username.equals ("Chhliu")) {//if the requested parameter is not empty and the value is Chhliu, theCtx.setsendzuulresponse (true);//to route the requestCtx.setresponsestatuscode ( $); CTX.Set("issuccess",true);//set the value so that the next filter sees the state of the previous filter return NULL; }Else{ctx.setsendzuulresponse (false);//Filter the request and do not route itCtx.setresponsestatuscode (401);//return error codeCtx.setresponsebody ("{\ "result\": \ "username is not correct!\"}");//return error contentCTx.Set("issuccess",false); return NULL; }} @Override PublicBoolean shouldfilter () {return true;//whether to execute the filter, which is true here, indicates the need to filter} @Override Public intFilterorder () {return 0;//priority is 0, the higher the number, the lower the priority level} @Override PublicString FilterType () {return "Pre";//front-facing filter } }
By inheriting the zuulfilter and then covering the 4 methods above, you can implement a simple filter, which is explained in the following notes.
FilterType: Returns a String representing the type of filter, and defines the filter type for four different lifecycles in Zuul, as follows:
pre
: Can be called before the request is routed
route
: Called when a request is routed
post
: Called after the route and error filters
error
: Called when an error occurs while processing a request
Zuul's main request lifecycle includes stages such as "pre", "route" and "post". For each request, all filters with these types will be run.
filterOrder
: Defines the order of execution of the filter by int value
shouldFilter
: Returns a Boolean type to determine if the filter is to be executed, so the filter can be switched by this function. In the example above, we return true directly, so the filter is always in effect
run
: The specific logic of the filter. It is important to note that here we ctx.setSendZuulResponse(false)
filter the request by making Zuul, not routing it, and then by ctx.setResponseStatusCode(401)
setting its return error code
Co-ordination between filters
Filters do not have a direct way to access each other. They can use RequestContext shared state, this is a map-like structure, with some explicit accessor methods used to be considered as Zuul primitives, the internal use of threadlocal implementation, interested students can see the source.
Build a filter and filter by password:
Package Com.chhliu.springcloud.zuul; Import Javax.servlet.http.HttpServletRequest; Import Com.netflix.zuul.ZuulFilter; Import Com.netflix.zuul.context.RequestContext; Public classAccesspasswordfilter extends Zuulfilter {@Override PublicObject Run () {RequestContext CTX=Requestcontext.getcurrentcontext (); HttpServletRequest Request=ctx.getrequest (); System. out. println (String.Format ("%s Accesspasswordfilter request to%s", Request.getmethod (), Request.getrequesturl (). toString ()); String username= Request.getparameter ("Password"); if(NULL! = Username && username.equals ("123456") {ctx.setsendzuulresponse (true); Ctx.setresponsestatuscode ( $); CTX.Set("issuccess",true); return NULL; }Else{ctx.setsendzuulresponse (false); Ctx.setresponsestatuscode (401); Ctx.setresponsebody ("{\ "result\": \ "password is not correct!\"}"); CTX.Set("issuccess",false); return NULL; }} @Override PublicBoolean shouldfilter () {RequestContext CTX=Requestcontext.getcurrentcontext (); return(Boolean) ctx.Get("issuccess");//If the result of the previous filter is true, then the previous filter succeeds and needs to enter the current filter, if the previous filter's result is false, then the previous filter did not succeed, the following filter action is not required, skip all subsequent filters and return the result } @Override Public intFilterorder () {return 1;//priority set to 1} @Override PublicString FilterType () {return "Pre"; } }
Finally, a post filter is built
Package Com.chhliu.springcloud.zuul; Import Javax.servlet.http.HttpServletRequest; Import Com.netflix.zuul.ZuulFilter; Import Com.netflix.zuul.context.RequestContext; Public classAccesstokenfilter extends Zuulfilter {@Override PublicObject Run () {RequestContext CTX=Requestcontext.getcurrentcontext (); HttpServletRequest Request=ctx.getrequest (); System. out. println (String.Format ("%s Accesstokenfilter request to%s", Request.getmethod (), Request.getrequesturl (). toString ()); Ctx.setsendzuulresponse (true); Ctx.setresponsestatuscode ( $); Ctx.setresponsebody ("{\ "name\": \ "chhliu\"}");//Output Final Result return NULL; } @Override PublicBoolean shouldfilter () {return true; } @Override Public intFilterorder () {return 0; } @Override PublicString FilterType () {return "Post";//after the request is processed, the filter is entered } }
2, in the main class, first open the previous two filters
@Bean Public Accessusernamefilter Accessusernamefilter () { returnnew Accessusernamefilter () ; } @Bean public accesspasswordfilter accesspasswordfilter () { return New Accesspasswordfilter (); }
3. Input request, verify
(1) The request is: Http://localhost:8768/h2service/user/1?username=chhliu
The test results are:
{"Result": "Password is not correct!"}
Console Print Results
Get Accessusernamefilter request to http://LOCALHOST:8768/H2SERVICE/USER/1 get Accesspasswordfilter request to http://LOCALHOST:8768/H2SERVICE/USER/1
Passed the Accessusernamefilter filter and failed to validate the Accesspasswordfilter filter.
No SQL print in the background, indicating that the request was not routed
(2) The request is: http://localhost:8768/h2service/user/1?password=123456
The test results are:
{"Result": "Username is not correct!"}
Console Print Results:
GET Accessusernamefilter request to http://LOCALHOST:8768/H2SERVICE/USER/1
Description to the Accessusernamefilter filter, but not to the Accesspasswordfilter filter, because the Accessusernamefilter filter priority higher, will be executed first, at the time of execution, The filter was found to be out of compliance, and then all filters were skipped, and the results were returned.
No SQL print in the background, indicating that the request was not routed
(3) The request is: Http://localhost:8768/h2service/user/1?password=123456&username=chhliu
The test results are:
{ "ID":1, "username":"User1", "name":"Zhang San", " Age": -, "Balance":100.00 }
Results of the console printing:
{ "ID":1, "username":"User1", "name":"Zhang San", " Age": -, "Balance":100.00 }
Results of the console printing:
Get Accessusernamefilter request to http://LOCALHOST:8768/H2SERVICE/USER/1 get Accesspasswordfilter request to http://LOCALHOST:8768/H2SERVICE/USER/1
Note that the Accessusernamefilter is executed first and then executed Accesspasswordfilter which is also the smaller the value of the order that we said earlier, the higher the priority is the match.
At the same time the requested service has SQL output:
Select as as as as as from where user0_.id=?
Indicates that the request was routed.
4. Turn on the post filter and run again
Test Result: The post filter was found to be last executed, although it had a priority of 0
For the life cycle of the Zuul filter, see
Note: There is a small mistake, routing should be the route
5. Expand
Zuul also provides a special type of filter, namely: Staticresponsefilter and Surgicaldebugfilter
Staticresponsefilter:Staticresponsefilter allows a response to be generated from the Zuul itself, rather than forwarding the request to the source.
Surgicaldebugfilter:Surgicaldebugfilter allows specific requests to be routed to a delimited debug cluster or host.
The filter details of spring Cloud-zuul