【问题标题】:How to redirect request to an URI passed in headers with Jetty AsyncProxyServlet如何将请求重定向到使用 Jetty AsyncProxyServlet 在标头中传递的 URI
【发布时间】:2025-12-04 09:20:04
【问题描述】:

我正在使用 SpringBoot、Jetty 和 kotlin 创建一个代理微服务。

这个微服务的目的是将我的前端应用程序发出的请求转发给外部服务(避免 CORS),并在检查一些自定义身份验证后发回响应。我将收到的查询将在标题中包含目标的 URL(即:Target-Url: http://domain.api/getmodel)。

基于this answer,我做了一个扩展AsyncProxyServlet的类并覆盖了sendProxyRequest的方法:

class ProxyServlet : AsyncProxyServlet() {

    private companion object {
        const val TARGET_URL = "Target-Url"
    }

    override fun sendProxyRequest(clientRequest: HttpServletRequest, proxyResponse: HttpServletResponse, proxyRequest: Request) {
        // authentication logic

        val targetUrl = clientRequest.getHeader(TARGET_URL)

        if (authSuccess) {
            super.sendProxyRequest(clientRequest, proxyResponse, proxyRequest)
        } else {
            proxyResponse.status = HttpStatus.UNAUTHORIZED.value()
        }
    }

}

当我查询我的代理时,我进入此方法并成功验证,但我不明白如何使用我的 targetUrl 来重定向请求。

该方法在将原始请求重定向到自身时不断调用自身(从http://myproxy:port/http://myproxy:port/ 的请求)。

这个jetty的具体实现很难找到文档,*是我最后的选择!

【问题讨论】:

    标签: spring-boot proxy kotlin jetty


    【解决方案1】:

    首先,为 Jetty 设置日志记录,并为包命名空间 org.eclipse.jetty.proxy 配置 DEBUG 级别的日志记录,这将有助于您更好地了解行为。

    Request proxyRequest 参数表示一个 HttpClient/Request 对象,该对象是使用不可变的 URI/URL 目标创建的(这是由于需要来自 URI/URL 的信息的各种其他功能,例如连接池、Cookie、身份验证、等),事后您无法更改此对象上的 URI/URL,您必须使用正确的 URI/URL 创建 HttpClient/Request 对象。

    由于您要做的只是更改目标 URL,因此您应该重写该方法...

    protected String rewriteTarget(HttpServletRequest clientRequest)
    

    ... 并将新的绝对 URI 字符串返回到您要使用的目的地(您的场景中的 "Target-Url" 标头看起来很不错)

    您可以在 ProxyServlet.service(HttpServletRequest, HttpServletResponse) 代码块(AsyncProxyServlet 扩展自)中看到此逻辑

    【讨论】:

    • 谢谢!我没有看到您的答案,并最终在今天早上实施了这个确切的解决方案。至少我是为自己学习的,我希望有一天这能帮助到其他人。