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

Java Web 登入攔截器實戰:Filter 實現用戶認證與白名單機制

     編輯:Java 相關知識

核心代碼:CheckLoginFilter

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.*;

public class CheckLoginFilter implements Filter {

    protected FilterConfig filterConfig = null;
    private String redirectURL = null;           // 未登入重定向頁面(不含 ContextPath)
    private List notCheckURLList = new ArrayList<>(); // 白名單 URL 列表
    private String sessionKey = null;            // Session 中存放用戶標識的鍵

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        HttpSession session = request.getSession();

        // 未配置 sessionKey 直接放行
        if (sessionKey == null) {
            chain.doFilter(request, response);
            return;
        }

        // 非白名單 且 Session 無用戶標識 → 重定向登入頁
        if (!checkRequestURIIntNotFilterList(request) && session.getAttribute(sessionKey) == null) {
            response.sendRedirect(request.getContextPath() + redirectURL);
            return;
        }

        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        notCheckURLList.clear();
    }

    /** 判斷當前請求 URI 是否在白名單中 */
    private boolean checkRequestURIIntNotFilterList(HttpServletRequest request) {
        String uri = request.getServletPath() +
                (request.getPathInfo() == null ? "" : request.getPathInfo());
        return notCheckURLList.contains(uri);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        redirectURL = filterConfig.getInitParameter("redirectURL");
        sessionKey = filterConfig.getInitParameter("checkSessionKey");

        String notCheckURLListStr = filterConfig.getInitParameter("notCheckURLList");
        if (notCheckURLListStr != null) {
            StringTokenizer st = new StringTokenizer(notCheckURLListStr, ";");
            notCheckURLList.clear();
            while (st.hasMoreTokens()) {
                notCheckURLList.add(st.nextToken());
            }
        }
    }
}

web.xml 配置範例

<filter>
    <filter-name>CheckLoginFilter</filter-name>
    <filter-class>com.example.filter.CheckLoginFilter</filter-class>
    <init-param>
        <param-name>checkSessionKey</param-name>
        <param-value>currentUser</param-value>  <!-- Session 屬性鍵 -->
    </init-param>
    <init-param>
        <param-name>redirectURL</param-name>
        <param-value>/login.jsp</param-value>   <!-- 登入頁相對路徑 -->
    </init-param>
    <init-param>
        <param-name>notCheckURLList</param-name>
        <param-value>/login.jsp;/register.jsp;/static/;</param-value> <!-- 白名單,分號分隔 -->
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CheckLoginFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

設計亮點解析

特性實現方式
配置外置化所有關鍵參數透過 web.xml init-param 注入,無需改代碼。
白名單機制支援靜態資源、登入頁、註冊頁等無需認證的路徑,分號分隔靈活擴展。
Session 鍵可配置適配不同業務對用戶標識的命名習慣(如 user、currentUser、token)。
路徑匹配精確使用 getServletPath() + getPathInfo() 獲取完整請求路徑,避免漏攔截。
資源釋放destroy() 清空白名單列表,防止內存洩漏。

擴展建議

  • 若專案使用 Spring,建議改用 HandlerInterceptor 或 Spring Security,功能更豐富。
  • 白名單支援 Ant 風格通配符(如 /api/public/**)可引入 AntPathMatcher 增強匹配能力。
  • 集群環境下 Session 共享需配合 Redis/Sticky Session 方案。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved