如何使用 Jetty 嵌入服务器在 Spring Cloud Zuul 过滤器中检索 HTTP2 框架设置?
How do you retrieve HTTP2 frame settings in a Spring Cloud Zuul filter with Jetty embed server?
背景
我目前正在从事一个项目,该项目研究各种 HTTP 被动指纹识别技术以确保安全。我计划对请求进行指纹识别的某些方面包括客户端问候、header 顺序、HTTP2 框架设置和 HTTP2 伪 header 顺序。到目前为止,我已经实现了一个解决方案,通过扩展 Jetty 的 org.eclipse.jetty.util.ssl.SslContextFactory.Server
class 来包装 SSLEngine 实例,从客户端 hello 中检索密码套件、压缩方法和扩展。然后我可以在 Zuul 过滤器中访问客户端问候数据,如下所示:
private static final String SSL_SESSION_ATTRIBUTE = "org.eclipse.jetty.servlet.request.ssl_session";
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
SSLSession sslSession = (SSLSession) request.getAttribute(SSL_SESSION_ATTRIBUTE);
ClientHello clientHello = (ClientHello) sslSession.getValue("client-hello");
return null;
}
有关 HTTP2 指纹识别的更多信息:
问题
虽然 Spring、Netflix Zuul 和 Jetty 嵌入式服务器有详尽的文档,但我一直无法找到一种方法来实现类似的检索 HTTP2 框架设置的解决方案。
您可以扩展 HTTP2ServerConnectionFactory
并将 protected ServerSessionListener newSessionListener(Connector connector, EndPoint endPoint)
覆盖为 return 您的自定义实现(可以委托给原始实现)。
通过这种方式,您可以访问低级 HTTP/2 帧(作为对象,而不是字节格式),这可能允许您对客户端进行指纹识别。
用于详细说明 @sbordet 答案的最小代码示例。
You can extend HTTP2ServerConnectionFactory and override protected > ServerSessionListener newSessionListener(Connector connector, EndPoint > endPoint) to return your custom implementation (that may delegate to the original implementation).
MyServerSessionListener.java
public class MyServerSessionListener implements ServerSessionListener {
private final ServerSessionListener delegate;
public MyServerSessionListener(ServerSessionListener delegate) {
this.delegate = delegate;
}
...
@Override
public void onSettings(Session session, SettingsFrame settingsFrame) {
Map<Integer, Integer> settings = settingsFrame.getSettings();
RequestContext context = RequestContext.getCurrentContext();
context.set("http2-frame-settings", settings);
delegate.onSettings(session, settingsFrame);
}
}
MyHTTP2ConnectionFactory.java
public class MyHTTP2ServerConnectionFactory extends HTTP2ServerConnectionFactory {
public MyHTTP2ServerConnectionFactory(HttpConfiguration httpConfiguration) {
super(httpConfiguration);
}
public MyHTTP2ServerConnectionFactory(HttpConfiguration httpConfiguration, String... protocols) {
super(httpConfiguration, protocols);
}
@Override
protected ServerSessionListener newSessionListener(Connector connector, EndPoint endPoint) {
ServerSessionListener delegate = super.newSessionListener(connector, endPoint);
return new MyServerSessionListener(delegate);
}
}
MyFilter.java
public class MyFilter extends ZuulFilter {
...
@Override
public Object run() {
RequestContext context = RequestContext.getCurrentContext();
Map<Integer, Integer> http2FrameSettings = (Map<Integer, Integer>) context.get("http2-frame-settings");
return null;
}
}
背景
我目前正在从事一个项目,该项目研究各种 HTTP 被动指纹识别技术以确保安全。我计划对请求进行指纹识别的某些方面包括客户端问候、header 顺序、HTTP2 框架设置和 HTTP2 伪 header 顺序。到目前为止,我已经实现了一个解决方案,通过扩展 Jetty 的 org.eclipse.jetty.util.ssl.SslContextFactory.Server
class 来包装 SSLEngine 实例,从客户端 hello 中检索密码套件、压缩方法和扩展。然后我可以在 Zuul 过滤器中访问客户端问候数据,如下所示:
private static final String SSL_SESSION_ATTRIBUTE = "org.eclipse.jetty.servlet.request.ssl_session";
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
SSLSession sslSession = (SSLSession) request.getAttribute(SSL_SESSION_ATTRIBUTE);
ClientHello clientHello = (ClientHello) sslSession.getValue("client-hello");
return null;
}
有关 HTTP2 指纹识别的更多信息:
问题
虽然 Spring、Netflix Zuul 和 Jetty 嵌入式服务器有详尽的文档,但我一直无法找到一种方法来实现类似的检索 HTTP2 框架设置的解决方案。
您可以扩展 HTTP2ServerConnectionFactory
并将 protected ServerSessionListener newSessionListener(Connector connector, EndPoint endPoint)
覆盖为 return 您的自定义实现(可以委托给原始实现)。
通过这种方式,您可以访问低级 HTTP/2 帧(作为对象,而不是字节格式),这可能允许您对客户端进行指纹识别。
用于详细说明 @sbordet 答案的最小代码示例。
You can extend HTTP2ServerConnectionFactory and override protected > ServerSessionListener newSessionListener(Connector connector, EndPoint > endPoint) to return your custom implementation (that may delegate to the original implementation).
MyServerSessionListener.java
public class MyServerSessionListener implements ServerSessionListener {
private final ServerSessionListener delegate;
public MyServerSessionListener(ServerSessionListener delegate) {
this.delegate = delegate;
}
...
@Override
public void onSettings(Session session, SettingsFrame settingsFrame) {
Map<Integer, Integer> settings = settingsFrame.getSettings();
RequestContext context = RequestContext.getCurrentContext();
context.set("http2-frame-settings", settings);
delegate.onSettings(session, settingsFrame);
}
}
MyHTTP2ConnectionFactory.java
public class MyHTTP2ServerConnectionFactory extends HTTP2ServerConnectionFactory {
public MyHTTP2ServerConnectionFactory(HttpConfiguration httpConfiguration) {
super(httpConfiguration);
}
public MyHTTP2ServerConnectionFactory(HttpConfiguration httpConfiguration, String... protocols) {
super(httpConfiguration, protocols);
}
@Override
protected ServerSessionListener newSessionListener(Connector connector, EndPoint endPoint) {
ServerSessionListener delegate = super.newSessionListener(connector, endPoint);
return new MyServerSessionListener(delegate);
}
}
MyFilter.java
public class MyFilter extends ZuulFilter {
...
@Override
public Object run() {
RequestContext context = RequestContext.getCurrentContext();
Map<Integer, Integer> http2FrameSettings = (Map<Integer, Integer>) context.get("http2-frame-settings");
return null;
}
}