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

如何在Jetty 10.0.12中判断Servlet请求是否为内部请求?

嵌入式Jetty 10.0.12内部API请求过滤实现

针对你的需求,这里提供几个可靠的方案来判断请求是否来自同一JVM内的其他Servlet:

方案一:自定义内部请求标记(最可靠)

核心思路是让内部发起请求的Servlet在调用内部API时,添加一个只有内部系统知道的自定义属性,Filter通过检查这个属性来放行请求。

修改Filter代码:

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

public class InternalFilter implements Filter {
    // 自定义内部标记的属性名,建议用唯一的包名前缀避免冲突
    private static final String INTERNAL_REQUEST_MARKER = "com.yourcompany.internal.request";

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
        // 检查是否存在内部请求标记
        if (Boolean.TRUE.equals(request.getAttribute(INTERNAL_REQUEST_MARKER))) {
            chain.doFilter(request, response);
            return;
        }

        // 非内部请求,返回403禁止访问
        HttpServletResponse httpResp = (HttpServletResponse) response;
        httpResp.sendError(HttpServletResponse.SC_FORBIDDEN, "Internal API only");
    }
}

内部Servlet调用示例:

当其他内部Servlet需要访问这个API时,通过RequestDispatcher转发或包含请求,并添加标记:

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class SomeInternalServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 添加内部请求标记
        req.setAttribute(InternalFilter.INTERNAL_REQUEST_MARKER, true);
        // 转发到内部API Servlet
        req.getRequestDispatcher("/internal-api-path").forward(req, resp);
    }
}

方案二:利用Jetty内部请求标识

Jetty的org.eclipse.jetty.server.Request类提供了判断内部分发的方法,当请求是通过RequestDispatcher转发/包含(同一JVM内)时,会被标记为内部请求。

修改Filter代码:

import org.eclipse.jetty.server.Request;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class InternalFilter implements Filter {
    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
        // 将ServletRequest转换为Jetty的Request对象
        if (request instanceof Request jettyRequest) {
            // 判断是否是内部分发请求(转发/包含)
            if (jettyRequest.isInternalDispatch()) {
                chain.doFilter(request, response);
                return;
            }
        }

        // 非内部请求,返回403
        HttpServletResponse httpResp = (HttpServletResponse) response;
        httpResp.sendError(HttpServletResponse.SC_FORBIDDEN, "Internal API only");
    }
}

注意:这个方法仅适用于通过RequestDispatcher发起的内部请求,如果你是通过HTTP客户端直接调用(即使是同一JVM内的HTTP客户端),不会被标记为内部分发,此时需要用方案一。

方案三:检查请求来源地址(局限性较大)

如果你的内部API仅允许本地回环地址访问,可以检查请求的远程地址是否为回环地址(如127.0.0.1、localhost、[::1]):

修改Filter代码:

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

public class InternalFilter implements Filter {
    private static final Set<String> INTERNAL_IPS = Set.of("127.0.0.1", "0:0:0:0:0:0:0:1", "localhost");

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
        String remoteAddr = request.getRemoteAddr();
        String remoteHost = request.getRemoteHost();

        if (INTERNAL_IPS.contains(remoteAddr) || INTERNAL_IPS.contains(remoteHost)) {
            chain.doFilter(request, response);
            return;
        }

        HttpServletResponse httpResp = (HttpServletResponse) response;
        httpResp.sendError(HttpServletResponse.SC_FORBIDDEN, "Internal API only");
    }
}

缺点:如果服务器允许外部访问回环地址(比如容器端口映射到外部),这个方法会有安全风险,仅建议在严格隔离的环境中使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 13:50:31