SpringBoot中实现拦截器级别的URl访问过快拦截,并利用JPA实现IP黑名单的功能。
今天给大家介绍一下SpringBoot中实现拦截器级别URl过快访问拦截,并利用JPA实现IP黑名单的功能。想学习分布式、微服务、JVM、多线程、架构、java、python的童鞋,千万不要扫码,否则后果自负~上一节中已经将中已经介绍了在控制器层面上面的URL拦截,这一节则侧重于网站全局式的拦截。就是不管输入什么URL地址都会进行过滤,判断是否存在URL访问过快的情况发生。因为本文会用...
今天给大家介绍一下SpringBoot中实现拦截器级别URl过快访问拦截,并利用JPA实现IP黑名单的功能。
史上最全Java技术栈面试题都在这里面了:Java面试题
上一节中已经将中已经介绍了在控制器层面上面的URL拦截,这一节则侧重于网站全局式的拦截。就是不管输入什么URL地址都会进行过滤,判断是否存在URL访问过快的情况发生。因为本文会用到前面已经讲过的JPA和拦截器技术,所以接下来就不对JPA和拦截器的实现过程进行认真的讲解了。有需要的朋友可以看我以前写的博客案例。
步骤一:下面先新建一张IP黑名单表,表的结构如下所示:
步骤二:新建一个实体类,并于黑名单表相映射。例子代码如下:
package example.entity;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "blacklist")
public class Blacklist {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(name = "ip", nullable = true, length = 30)
private String ip;
@Temporal(TemporalType.TIMESTAMP)
private Date iptime; // 日期类型,格式:yyyy-MM-dd HH:mm:ss
public Blacklist() {
}
public Blacklist(String ip, Date iptime) {
this.ip = ip;
this.iptime = iptime;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public Date getIptime() {
return iptime;
}
public void setIptime(Date iptime) {
this.iptime = iptime;
}
}
步骤三:新建一个黑名单的数据库操作类,也就是dao类。例子代码如下:
package example.dao;
import example.entity.Blacklist;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
import java.util.List;
@Transactional
@Repository
public interface BlacklistDao extends JpaRepository<Blacklist, Integer> {
public List<Blacklist> findByIp(String ip);
}
步骤四:新建一个过滤器类,并实现对URL访问过快的拦截,并将那些攻击者的IP加入黑名单中去。例子代码如下:
package example.Interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import example.controller.exception.RequestLimitException;
import example.controller.limit.RequestLimit;
import example.controller.limit.RequestLimitContract;
import example.dao.BlacklistDao;
import example.entity.Blacklist;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import java.util.*;
/**
* 自定义拦截器1
*
* @author 林志强(208017534)
* @myblog www.wolzq.com
* @create 2016年9月20日
*/
public class URLInterceptor implements HandlerInterceptor {
@Autowired
private BlacklistDao blacklistDao;
private Map<String, Integer> redisTemplate=new HashMap<String,Integer>();
private static final Logger logger = LoggerFactory.getLogger("RequestLimitLogger");
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
String ip = request.getLocalAddr();
List<Blacklist> blackList =blacklistDao.findByIp(ip);
if(blackList==null || blackList.size()==0){
urlHandle(request,10000,10);
}else{
modelAndView.setViewName("/errorpage/error");
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
public void urlHandle(HttpServletRequest request, long limitTime,int limitCount) throws RequestLimitException {
try{
String ip = request.getLocalAddr();
String url = request.getRequestURL().toString();
String key = "req_limit_".concat(url).concat(ip);
if(redisTemplate.get(key)==null || redisTemplate.get(key)==0){
redisTemplate.put(key,1);
}else{
redisTemplate.put(key,redisTemplate.get(key)+1);
}
int count = redisTemplate.get(key);
if (count > 0) {
Timer timer= new Timer();
TimerTask task = new TimerTask(){
@Override
public void run() {
redisTemplate.remove(key);
}
};
timer.schedule(task, limitTime);
}
if (count > limitCount) {
addHostHandle(ip);
throw new RequestLimitException();
}
} catch (RequestLimitException e) {
throw e;
} catch (Exception e) {
logger.error("发生异常: ", e);
}
}
public void addHostHandle(String ip){
Calendar calendar = Calendar.getInstance();
Date iptime=calendar.getTime();
Blacklist blacklist=new Blacklist(ip,iptime);
blacklistDao.save(blacklist);
}
}
步骤五:在拦截器添加类中加入bean方法,否则JPA不能自动注入成功,因为容器还未加载就已经实现拦截器的功能了。例子代码如下:
package example.configuration;
import example.Interceptor.ErrorInterceptor;
import example.Interceptor.URLInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class MyWebAppConfigurer
extends WebMvcConfigurerAdapter {
@Bean
public HandlerInterceptor getMyInterceptor(){
return new URLInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 多个拦截器组成一个拦截器链
// addPathPatterns 用于添加拦截规则
// excludePathPatterns 用户排除拦截
registry.addInterceptor(getMyInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
步骤六:在html资源文件下面新建一个错误界面,用于黑名单用户的跳转操作。例子代码如下:
<html>
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<h1>您已经被列入黑名单中,请及时和管理员联系,接触黑名单限制。。。。</h1>
</body>
</html>
这样就已经实现了拦截器级别URl访问过快拦截,并利用JPA实现IP黑名单的功能,是不是特别简单呀。
如果大家对文章有什么问题或者疑意之类的,可以加我订阅号在上面留言,订阅号上面我会定期更新最新博客。如果嫌麻烦可以直接加我wechat:lzqcode
更多推荐
所有评论(0)