Spring Cloud Zuul实现IP访问控制

接着上篇文章 https://www.cnblogs.com/mxmbk/p/9569438.html 

IP访问限制和黑白名单如何做,需要解决以下几个问题

1、如何识别正常访问和异常访问?(一段时间同一接口访问次数太多?高峰期和低峰期是否不同?

2、IP访问异常后拒绝策略是什么?(一段时间访问访问异常接口不能访问?高峰期和低峰期是否不同?

3、是否不同业务的识别方法和拒绝策略不一样?(有些接口访问频率高,有些访问频率低?

4、有些业务是否之后IP在白名单中才能访问?(只对第三方提供的接口?

5、IP访问异常的通知?(请求被识别为异常是否通知到服务维护人员?)

 

先提出问题,在想解决方案,第一版的简单基于Spring cloud zuul的实现方案如下:

具体实现(基于ZuulFilter的实现):

  

 1 package com.brightcns.wuxi.citizencard.zuulserver.filter;
 2 
 3 import com.alibaba.fastjson.JSONObject;
 4 import com.brightcns.wuxi.citizencard.common.feature.exception.SystemException;
 5 import com.brightcns.wuxi.citizencard.common.feature.util.IPUtils;
 6 import com.brightcns.wuxi.citizencard.common.feature.util.MD5Utils;
 7 import com.brightcns.wuxi.citizencard.zuulserver.constants.properties.IPLimitProperty;
 8 import com.brightcns.wuxi.citizencard.zuulserver.limit.AbstractIPLimitStrategy;
 9 import com.brightcns.wuxi.citizencard.zuulserver.limit.IPLimitFactory;
10 import com.google.common.collect.Lists;
11 import com.netflix.zuul.ZuulFilter;
12 import com.netflix.zuul.context.RequestContext;
13 import lombok.extern.slf4j.Slf4j;
14 import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
15 import javax.servlet.http.HttpServletRequest;
16 import java.util.List;
17 import static com.brightcns.wuxi.citizencard.order.constants.enums.ZuulErrorCode.IP_LIMIT;
18 
19 /**
20  * @author maxianming
21  * @date 2018/8/31 10:25
22  */
23 @Slf4j
24 public class IPLimitFilter extends ZuulFilter {
25     // 白名单URI
26     private List<String> excludeUrl = Lists.newArrayList("/health","/info");
27     // 响应类型
28     public final String JSON_TYPE = "application/json;charset=UTF-8";
29     
30     @Override
31     public String filterType() {
32         return FilterConstants.PRE_TYPE;
33     }
34 
35     @Override
36     public int filterOrder() {
37         return 0;
38     }
39 
40     @Override
41     public boolean shouldFilter() {
42         RequestContext context = RequestContext.getCurrentContext();
43         HttpServletRequest request = context.getRequest();
44         String requestUri = request.getRequestURI();
45         if (excludeUrl.contains(requestUri)) {
46             return false;
47         }
48         return true;
49     }
50 
51     @Override
52     public Object run() {
53         RequestContext context = RequestContext.getCurrentContext();
54         HttpServletRequest request = context.getRequest();
55         String requestIp = IPUtils.getIpAddress(request);
56         String requestUri = request.getRequestURI();
57         log.info("网关接受requestIp:[{}], requestUri:[{}]请求", requestIp, requestUri);
58         try {
59             AbstractIPLimitStrategy ipLimitStrategy = IPLimitFactory.getIPLimitStragy();
60             boolean result = ipLimitStrategy.isIPLimit(requestIp, requestUri);
61             if (result) {
62                 log.info("requestIp:{},requestUri:{}访问限制", requestIp, requestUri);
63                 context.setSendZuulResponse(false);
64                 context.setResponseStatusCode(200);
65                 context.setResponseBody(IP_LIMIT.getCode() + ":" + IP_LIMIT.getMsg());
66                 context.getResponse().setContentType(JSON_TYPE);
67             }
68         } catch (Exception e) {
69             log.error("IP限制异常", e);
70         }
71         return null;
72     }
73 
74 
75 
76 }

 1、基于ZuulFilter的简单实现,ZuulFilter的使用可以自行百度,可参考 https://blog.csdn.net/dream_broken/article/details/77197585

 2、63-66行代码 主要是Filter不继续执行其他Filter,响应JSON给调用端

3、59行和60行重点主要采用了策略模式(黑天和白天不同策略)涉及敏感信息 只表明思路
     具体思路:

  • 采用redis incby 和 expire进行访问次数的统计和有效期的设置
  • redis key的生成规则: PREFIX:IP:MD5(uri)
  • 黑名单暂时配置文件中配置

 

原文地址:https://www.cnblogs.com/mxmbk/p/9569712.html