如何使用 Jetty AsyncProxyServlet 将请求重定向到 headers 中传递的 URI

How to redirect request to an URI passed in headers with Jetty AsyncProxyServlet

我正在使用 SpringBoot、Jetty 和 kotlin 创建一个代理 micro-service。

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

基于,我做了一个class扩展了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/ to http://myproxy:port/ 的请求)。

很难找到有关 jetty 的具体实现的文档,Whosebug 是我最后的选择!

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

Request proxyRequest 参数表示 HttpClient/Request object,它是使用不可变的 URI/URL 目标创建的(这是由于各种其他功能需要来自URI/URL 例如连接池、Cookie、身份验证等),你不能在这个 object 上更改 URI/URL 事实上,你必须创建 HttpClient/Request object 与正确的 URI/URL.

由于您只想更改目标 URL,因此您应该覆盖方法 ...

protected String rewriteTarget(HttpServletRequest clientRequest)

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

您可以在 ProxyServlet.service(HttpServletRequest, HttpServletResponse) 代码块(AsyncProxyServlet 扩展)

中看到此逻辑