Springboot实现IP⿊名单的完整步骤
⼀·业务场景和需要实现的功能
以redis作为IP存储地址实现。
业务场景:针对秒杀活动或者常规电商业务场景等,防⽌恶意脚本不停的刷接⼝。
实现功能:写⼀个拦截掉⿊名单IP,额外增加⼀个接⼝,将ip地址添加到redis中,并且返回redis中当前全部ip ⼆·Springboot中定义⼀个
@Order(0)
@Aspect
@Component
public class AopInterceptor {
/**
* 定义规则
*/
@Pointcut("execution(* st.*(..))")
public void pointCut() {
}
/**
* 具体实现
*
* @throws Throwable
*/
@Around(value = "pointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
try {
HttpServletRequest request = ((ServletRequestAttributes) RequestAttributes()).getRequest();
//判断是否为⿊名单⽤户
String ip = getIpAddress(request);
if (checkIpBlack(ip)) {
//ip在⿊名单中返回false
//return false;
DefaultResponse defaultResponse = new DefaultResponse();
defaultResponse.setCode(-1);
defaultResponse.setMessage("ip在⿊名单中,拒绝访问.");
SysLogHelper.log("IpBlackAopInterceptor", "当前请求ip" + ip, "ip在⿊名单中,拒绝访问");
return defaultResponse;
} else {
//ip不在⿊名单中返回true
SysLogHelper.log("IpBlackAopInterceptor", "当前请求ip" + ip, "ip正常,允许访问");
return point.proceed();
}
} catch (Exception e) {
e.printStackTrace();
<("IpBlackAopInterceptor⿊名单拦截异常:", Message(e) + "详细" + StackTrace(e), null);  }
Args();
}
//对⽐当前请求IP是否在⿊名单中,注意(对⽐⿊名单ip存放在redis中)
public boolean checkIpBlack(String ip) throws Exception {
IpBlackBody body = new IpBlackBody();
body = ("IpBlack:ips", IpBlackBody.class);
if (body != null) {
for (int i = 0; i < Ip().length; i++) {
if (Ip()[i].equals(ip))
return true;
}
}
return false;
}
}
三·获取请求主机IP地址
public final static String getIpAddress(HttpServletRequest request)
throws IOException {
// 获取请求主机IP地址,如果通过代理进来,则透过防⽕墙获取真实IP地址
String ip = Header("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
if (ip == null || ip.length() == 0
|| "unknown".equalsIgnoreCase(ip)) {
ip = Header("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0
|| "unknown".equalsIgnoreCase(ip)) {
ip = Header("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0
|| "unknown".equalsIgnoreCase(ip)) {
ip = Header("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0
|| "unknown".equalsIgnoreCase(ip)) {
ip = Header("HTTP_X_FORWARDED_FOR");
springboot和过滤器}
if (ip == null || ip.length() == 0
|| "unknown".equalsIgnoreCase(ip)) {
ip = RemoteAddr();
}
} else if (ip.length() > 15) {
String[] ips = ip.split(",");
for (int index = 0; index < ips.length; index++) {
String strIp = (String) ips[index];
if (!("unknown".equalsIgnoreCase(strIp))) {
ip = strIp;
break;
}
}
}
return ip;
}
四·扩展接⼝,实现将⿊名单IP写⼊redis当中,并返回当前所有⿊名单IP
@RestController
public class IpBlackController {
@Autowired(required = false)
private CacheHelper cacheHelper;
@PostMapping("/testIpBlack")
public IpBlackBody IpBlack(@RequestBody IpBlackBody ipBlackBody) throws Exception {  IpBlackBody body = new IpBlackBody();
body = ("IpBlack:ips", IpBlackBody.class);
if (body != null) {
//拼接当前IP与redis中现有ip
Ip(), Ip());
//将数据赋给body
body.setIp(Ip(), Ip()));
//setex中第⼆个参数时间为S,根据业务场景相应调整,此处我设置为⼀天
//将body中拼接后的ip地址数据写⼊redis中
cacheHelper.setex("IpBlack:ips", 86400, body);
} else {
cacheHelper.setex("IpBlack:ips", 86400, ipBlackBody);
body = ("IpBlack:ips", IpBlackBody.class);
return body;
}
return body;
}
//拼接两个String[]的⽅法
public static String[] linkArray(String[] array1, String[] array2) {
List<String> list = new ArrayList<>();
if (array1 == null) {
return array2;
}
if (array2 == null) {
return array1;
}
for (int i = 0; i < array1.length; i++) {
list.add(array1[i]);
}
for (int i = 0; i < array2.length; i++) {
list.add(array2[i]);
}
String[] returnValue = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
returnValue[i] = (i);
}
return returnValue;
}
}
总结:
⾸先根据需要拦截的controller拦截响应请求controller层,然后根据编写相关的具体实现,其中包含两部主要操作:
1.获取到远程请求主机的实际ip地址
2.对⽐当前ip是否在⿊名单中(此次操作需要读取redis中的⿊名单ip列表)
然后根据当前需求增加了⼀个redis接⼝,实现将需要封禁的IP地址增加到redis⿊名单中并返回当前所有的⿊名单IP地址。⾄此:⾄此springboot通过实现拦截⿊名单功能已经实现。
到此这篇关于Spring boot实现IP⿊名单的⽂章就介绍到这了,更多相关SpringbootIP⿊名单内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!