马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
在实际项目使用中,必须要考虑服务的安全性,当服务部署到互联网以后,就要考虑服务被恶意请求和暴力攻击的情况,下面的教程,通过Spring Boot提供的HandlerInterceptor和Redis 针对 Url + ip在一定时间内访问的次数来将ip禁用,可以根据自己的业务需求进行相应的修改,以达到自己的目的。
首先创建一个自定义的拦截器类,也是最核心的代码。- /**
- * @ProjectName: cdkj-framework
- * @Package: com.cdkjframework.core.spring.filter
- * @ClassName: FilterHandlerInterceptor
- * @Description: 拦截过滤
- * @Author: xiaLin
- * @Date: 2022/6/22 13:36
- * @Version: 1.0
- */
- public class FilterHandlerInterceptor implements HandlerInterceptor {
- /**
- * 日志
 - */
- private LogUtils logUtils = LogUtils.getLogger(FilterHandlerInterceptor.class);
- /**
- * redis锁
- */
- private final RedisLettuceLock redisLettuceLock;
- /**
- * IP头部变量(可能通过Nginx代理后)
- */
- private static final String HEADER_IP = "X-Real-IP";
- /**
- * 锁IP请求URL地址KEY
- */
- private static final String LOCK_IP_URL_KEY = "lock_ip_";
- /**
- * IP请求URL地址时间
- */
- private static final String IP_URL_REQ_TIME = "ip_url_times_";
- /**
- * 极限时间
- */
- private static final long LIMIT_TIMES = 5;
- /**
- * IP锁定时间 秒
- */
- private static final int IP_LOCK_TIME = 60;
- /**
- * 构建函数
- */
- public FilterHandlerInterceptor(RedisLettuceLock redisLettuceLock) {
- this.redisLettuceLock = redisLettuceLock;
- }
- /**
- * 预处理
- *
- * @param request 请求
- * @param response 响应
- * @param o 参数
- * @return 返回结果
- * @throws Exception 异常信息
- */
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
- String ip = request.getHeader(HEADER_IP);
- if (StringUtils.isNullAndSpaceOrEmpty(ip)) {
- ip = request.getRemoteAddr();
- }
- logUtils.info("request 请求地址 Uri={},ip={}", request.getRequestURI(), ip);
- if (ipIsLock(ip)) {
- logUtils.info("ip访问被禁止={}", ip);
- ResponseBuilder builder = ResponseBuilder.failBuilder("ip访问被禁止");
- returnJson(response, builder);
- return false;
- }
- if (!addRequest(ip, request.getRequestURI())) {
- ResponseBuilder builder = ResponseBuilder.failBuilder("ip访问被禁止");
- returnJson(response, builder);
- return false;
- }
- return true;
- }
- @Override
- public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
- }
- @Override
- public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
- }
- /**
- * IP 是否已锁
- *
- * @param ip IP 地址
- * @return 返回是否成功
- */
- private Boolean ipIsLock(String ip) {
- if (redisLettuceLock.lock(LOCK_IP_URL_KEY + ip)) {
- return true;
- }
- return false;
- }
- /**
- * 添加请求信息
- *
- * @param ip IP 地址
- * @param uri 请求路径
- * @return 返回是否成功
- */
- private Boolean addRequest(String ip, String uri) {
- String key = IP_URL_REQ_TIME + ip + uri;
- if (RedisUtils.syncExists(key)) {
- long time = RedisUtils.syncIncr(key, IntegerConsts.ONE);
- if (time >= LIMIT_TIMES) {
- redisLettuceLock.lock(LOCK_IP_URL_KEY + ip, IP_LOCK_TIME, ip);
- return false;
- }
- } else {
- redisLettuceLock.lock(key, (long) IntegerConsts.ONE, IntegerConsts.ONE);
- }
- return true;
- }
- /**
- * 返回结果
- *
- * @param response 响应
- * @param builder 返回结果
- * @throws Exception 异常信息
- */
- private void returnJson(HttpServletResponse response, ResponseBuilder builder) throws Exception {
- ResponseUtils.out(response, builder);
- }
- }
复制代码 最后将上面自定义的拦截器通过WebMvcConfigurer下的registry.addInterceptor添加一下,就生效了。- /**
- * @ProjectName: cdkj-framework
- * @Package: com.cdkjframework.core.spring.filter
- * @ClassName: WebMvcFilterConfigurerAdapter
- * @Description: java类作用描述
- * @Author: xiaLin
- * @Date: 2022/6/22 13:37
- * @Version: 1.0
- */
- @RequiredArgsConstructor
- public class WebMvcFilterConfigurerAdapter implements WebMvcConfigurer {
- /**
- * redis锁
- */
- private final RedisLettuceLock redisLettuceLock;
- /**
- * 过虑句柄拦截器
- *
- * @return 返回拦截器
- */
- @Bean
- private FilterHandlerInterceptor filterHandlerInterceptor() {
- return new FilterHandlerInterceptor(redisLettuceLock);
- }
- /**
- * 添加 拦截器
- *
- * @param registry 拦截器注册
- */
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(filterHandlerInterceptor()).addPathPatterns("/**");
- }
- }
复制代码 自己可以写一个for循环来测试改功能,这里就不具体详细介绍了。
文章中的工具类可参考:https://gitee.com/cdkjframework/common/tree/1.0.2/
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |