You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Servlet登录页面认证绕过安全问题的原因与修复方案

问题原因分析

这个问题我之前在维护Java Web项目时也碰到过,核心原因很明确:你的Controller.java Servlet只处理了「登录表单提交」的场景,却没有对「直接访问Servlet」的请求做强制登录校验。

具体来说:

  • 目前的逻辑应该是只有当用户通过index.jsp提交登录表单(POST请求)时,才会调用Authenticator.java做账号密码验证,验证通过后跳转至Welcome.jsp;
  • 但如果用户直接通过GET请求访问http://localhost:8080/web-db-manager/Controller,Servlet并没有检查会话中是否存在已登录的用户标识,直接就执行了跳转逻辑,相当于把需要授权的入口完全暴露了。
修复方案

下面是一步步的具体修复方法,从基础到优化都有:

1. 登录成功后将用户状态存入Session

首先,在登录验证通过后,把用户的登录标识(比如用户名)存入HttpSession,这样后续请求就能通过Session判断用户是否已登录。在Controller.java的POST处理逻辑里添加:

// 当Authenticator验证通过后执行
if (auth.validate(username, password)) {
    HttpSession session = request.getSession();
    session.setAttribute("loggedInUser", username); // 存储已登录用户名,也可以存用户对象
    request.getRequestDispatcher("Welcome.jsp").forward(request, response);
}

2. 给Controller.java添加全局登录校验

修改Controller.java的doGet和doPost方法,在处理任何请求前先检查Session中的登录状态:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 检查登录状态:false表示如果没有会话就不新建
    HttpSession session = request.getSession(false);
    if (session == null || session.getAttribute("loggedInUser") == null) {
        // 未登录,直接重定向回登录页
        response.sendRedirect("index.jsp");
        return;
    }
    // 已登录,继续跳转至Welcome.jsp
    request.getRequestDispatcher("Welcome.jsp").forward(request, response);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    
    Authenticator auth = new Authenticator();
    if (auth.validate(username, password)) {
        // 登录成功,存入Session
        HttpSession session = request.getSession();
        session.setAttribute("loggedInUser", username);
        request.getRequestDispatcher("Welcome.jsp").forward(request, response);
    } else {
        // 登录失败,返回登录页并提示错误
        request.setAttribute("loginError", "账号或密码错误");
        request.getRequestDispatcher("index.jsp").forward(request, response);
    }
}

3. 防止直接访问Welcome.jsp

除了Servlet,最好也在Welcome.jsp的开头添加校验,避免用户直接输入Welcome.jsp的URL绕过Servlet:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
    // 检查登录状态
    HttpSession session = request.getSession(false);
    if (session == null || session.getAttribute("loggedInUser") == null) {
        response.sendRedirect("index.jsp");
        return;
    }
%>
<!-- 以下是Welcome.jsp原有内容 -->
<!DOCTYPE html>
<html>
<head>
    <title>Welcome</title>
</head>
<body>
    <h1>欢迎你,<%= session.getAttribute("loggedInUser") %>!</h1>
</body>
</html>

4. 可选:用Filter统一拦截授权请求

如果以后项目中有更多需要登录才能访问的页面/Servlet,建议写一个统一的LoginFilter,避免每个Servlet都重复写校验逻辑:

public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
        
        // 定义不需要拦截的路径:登录页、登录提交的POST请求
        String requestURI = request.getRequestURI();
        if (requestURI.contains("index.jsp") || 
            (requestURI.contains("Controller") && request.getMethod().equalsIgnoreCase("POST"))) {
            chain.doFilter(req, res);
            return;
        }
        
        // 校验登录状态
        if (session == null || session.getAttribute("loggedInUser") == null) {
            response.sendRedirect("index.jsp");
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void destroy() {}
}

然后在web.xml中配置这个Filter:

<filter>
    <filter-name>LoginFilter</filter-name>
    <filter-class>com.yourpackage.LoginFilter</filter-class> <!-- 替换成你的Filter所在包路径 -->
</filter>
<filter-mapping>
    <filter-name>LoginFilter</filter-name>
    <url-pattern>/Welcome.jsp</url-pattern>
    <url-pattern>/Controller</url-pattern>
    <!-- 可以添加更多需要授权的路径,比如/admin/* -->
</filter-mapping>

内容的提问来源于stack exchange,提问作者Kavindu Ravishka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 23:54:09