首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java Web 入侵檢測實戰:基於 EasyJWeb 的防刷新機制設計與實現

     編輯:Java 程式設計入門

前言:軟性防禦的必要性

Web 應用常面臨惡意刷新、暴力遍歷、資料洩漏等威脅。硬體防火牆成本高、策略僵化;軟體層面的入侵檢測(IDS)可針對業務特徵精準攔截。本文基於 EasyJWeb 框架實戰代碼,展示一個基於 IP+用戶、時間窗口、閾值觸發的輕量級防刷新系統。

架構設計:三層職責分離

  1. 資料模型:UserConnect - 封裝單用戶訪問狀態
  2. 核心引擎:UserConnectManage - 多線程安全的檢測、記錄、清理邏輯
  3. 接入點:框架入口 / Filter - 所有請求的統一檢查關卡

核心代碼深度解析

1. 資料模型:UserConnect.java

public class UserConnect {
    private String userName;        // 用戶名/標識
    private String ip;              // 客戶端 IP
    private Date firstFailureTime;  // 首次違規時間(時間窗口起點)
    private Date lastLoginTime;     // 最近訪問時間
    private int failureTimes;       // 當前窗口內違規計數
    private int status = 0;         // 0=正常, -1=鎖定
    // Getter/Setter 略
}

2. 核心引擎:UserConnectManage.java(單例 + 後台清理線程)

public class UserConnectManage {
    // 靜態配置參數(可動態調整)
    private static int maxFailureTimes = 10;      // 最大允許違規次數
    private static long maxFailureInterval = 10000; // 時間窗口:10 秒
    private static long waitInterval = 60000;     // 鎖定冷卻期:60 秒
    private static int maxOnlineUser = 200;       // 最大在線用戶數(防記憶體溢出)

    private static final Map users = new HashMap<>(); // key: "ip:username"
    private static Thread checkThread = null;

    // 靜態內部類:後台定時清理線程(每 2 秒掃描)
    private static class CheckTimeOut implements Runnable {
        private final Thread parentThread;
        public CheckTimeOut(Thread parent) { this.parentThread = parent; }
        public void run() {
            while (parentThread.isAlive()) {
                try {
                    Thread.sleep(2000);
                    cleanExpiredEntries(); // 清理過期、超量條目
                } catch (Exception e) { e.printStackTrace(); }
            }
        }
    }

    // 核心檢測入口:返回 true=放行, false=攔截
    public static synchronized boolean checkLoginValidate(String ip, String userName) {
        String key = ip + ":" + userName;
        Date now = new Date();
        UserConnect uc = users.get(key);

        if (uc == null) { // 首次訪問
            uc = new UserConnect();
            uc.setIp(ip); uc.setUserName(userName);
            uc.setFailureTimes(0); uc.setFirstFailureTime(now);
            users.put(key, uc);
            if (checkThread == null) new CheckTimeOut(Thread.currentThread());
            return true;
        }

        // 核心判斷邏輯
        if (uc.getFailureTimes() > maxFailureTimes) {
            long elapsed = now.getTime() - uc.getFirstFailureTime().getTime();
            if (elapsed < maxFailureInterval) { // 窗口內超閾值
                uc.setStatus(-1); // 鎖定
                return false;
            } else if (uc.getStatus() == -1 && elapsed < (maxFailureInterval + waitInterval)) {
                return false; // 冷卻期內持續攔截
            } else {
                // 窗口已過,重置計數器
                uc.setFailureTimes(0);
                uc.setFirstFailureTime(now);
                uc.setStatus(0);
            }
        }

        uc.setFailureTimes(uc.getFailureTimes() + 1); // 計數+1
        return true;
    }

    // 清理策略:優先刪除過期,不足則強制刪除一半(保護記憶體)
    private static void cleanExpiredEntries() {
        // ... 遍歷 users,移除 firstFailureTime 超過 maxFailureInterval 的條目
        // 若刪除 < 5 個且總數仍超 maxOnlineUser,強制刪除一半最舊條目
    }

    // 輔助方法:reset/remove/clear 供登出、管理員解鎖使用
    // 配置 Getter/Setter 略
}

3. 接入點:ActionServlet 中的攔截

public class ActionServlet extends HttpServlet {
    public void service(HttpServletRequest request, HttpServletResponse response) {
        // 入侵檢測:第一道關卡
        if (!UserConnectManage.checkLoginValidate(request.getRemoteAddr(), "guest")) {
            String msg = "您對頁面的刷新太快,請等待" + 
                         (UserConnectManage.getWaitInterval()/1000) + "秒後再刷新頁面!";
            info(request, response, new Exception(msg)); // 友好錯誤頁
            return; // 直接終止後續處理
        }
        // ... 正常業務分發流程
    }
}

關鍵設計決策解析

決策點方案理由
識別維度IP + 用戶名兼顧匿名用戶(IP)與登入用戶(用戶名),防止代理 IP 誤傷
時間窗口滑動窗口以首次違規時間為起點,避免固定窗口邊界被繞過
鎖定機制狀態機:正常→鎖定→冷卻→正常防止瞬時高頻後立即恢復,給予懲罰期
記憶體保護最大在線數 + 定時清理 + 強制淘汰防止惡意構造大量 Key 耗盡 Heap
併發安全方法級 synchronized + 靜態 Map簡單有效,寫少讀多場景性能可接受

擴展方向與局限

可擴展檢測維度

  • User-Agent 異常(爬蟲特徵)
  • 請求路徑異常(掃描器遍歷)
  • 參數範圍異常(ID 遍歷、SQL 注入嘗試)
  • 行為序列異常(繞過業務流程直接訪問敏感接口)

已知局限

  • 單點記憶體存儲:叢集環境需改用 Redis/資料庫共享狀態
  • 靜態配置:生產環境建議外部化配置(Spring @Value、Apollo、Nacos)
  • 無白名單機制:需增加管理員/爬蟲白名單避免誤攔

結語:最好的防禦是業務感知的防禦

這套機制在 EasyJWeb 官網(bbs.easyjf.com)穩定運行多年,有效遏制了惡意刷新。核心啟示:入侵檢測不應是通用規則的堆砌,而應是針對具體業務場景(刷新頻率、登入失敗、資料遍歷)的精準建模。從這裡開始,構建你自己的業務安全防線。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved