我正在使用 Jgit 库在我们的应用程序中提供 git 功能。当执行像clone这样的git操作来克隆HTTPS存储库时,请求需要经过我们创建的嵌入式jetty反向代理服务器,并在服务器中运行。
我们使用 JDK 1.8、Jgit - 5.13.1.202206130422-r 和 Jetty - 9.4.46.v20220331
我们在执行克隆请求之前设置代理信息,如下。
// this custom connection factory sets the proxy
CustomJdkHttpConnectionFactory connFactory = new CustomJdkHttpConnectionFactory();
command.setTransportConfigCallback(transport -> {
if (transport instanceof TransportHttp) {
TransportHttp transportHttp = (TransportHttp) transport;
Map<String, String> headers = new HashMap<>();
String authHeader = new String(Base64.getEncoder().encode(new String("admin" + ":" + "admin").getBytes()));
headers.put("Authorization", "Basic " + authHeader);
headers.put("Proxy-Authorization", "Basic " + authHeader);
transportHttp.setAdditionalHeaders(headers);
transportHttp.setHttpConnectionFactory(connFactory);
}
});
我们基于嵌入式码头的代理服务器看起来像这样
public void startHTTPProxyServer() throws Exception {
server = new Server();
ServerConnector connector = new ServerConnector(server);
String hostName = InetAddress.getLocalHost().getCanonicalHostName();
connector.setHost(hostName);
connector.setPort(PORT);
server.setConnectors(new Connector[] { connector });
// this custom connect handler will check the headers and execute the authorization check
ConnectHandler proxy = new CustomConnectHandler();
server.setHandler(proxy);
server.start();
}
自定义连接处理程序现在只是枚举标头。一旦找到正确的标头,我们将添加验证逻辑。
public class CustomConnectHandler extends ConnectHandler {
protected boolean handleAuthentication(HttpServletRequest request, HttpServletResponse response, String address) {
logger.info("Request received: " + request.getMethod() + " " + request.getRequestURI());
Enumeration<String> requestHeaderNames = request.getHeaderNames();
while (requestHeaderNames.hasMoreElements()) {
String headerName = requestHeaderNames.nextElement();
String headerValue = request.getHeader(headerName);
logger.info("Request Header : " + headerName + " = " + headerValue);
}
return false;
}
}
我们面临的问题是,我们传递的授权标头没有传播到基于嵌入式码头的代理服务器。据我了解,由于我们正在尝试连接到 HTTPS 存储库,因此客户端实际上发送了 CONNECT 请求,并且显然附加标头被删除。但是,除非标头存在,否则我们如何验证传入的授权?
有什么解决方法可以获取授权所需的这些附加标头吗?
CONNECT 请求本身可以进行身份验证,这就是使用签名覆盖
org.eclipse.jetty.server.handler.ConnectHandler
上的 Jetty 12 方法的目的...
protected boolean handleAuthentication(Request request, Response response, String address)
一旦获得批准(您已验证
Request
的身份验证并返回 true
),CONNECT 请求将响应给用户代理(Web 客户端),然后建立隧道连接。如果该连接使用 TLS,那么您将无法看到该隧道连接包含的内容(TLS 的全部意义)