访问 WebSocket @ServerEndpoint 中的 HttpServletRequest 属性 [英] Accessing HttpServletRequest properties within a WebSocket @ServerEndpoint
问题描述
我需要访问 HttpServletRequest
属性以获取 javax.servlet.request.X509Certificate,其中包含 TLS 证书的 X509Certificate
数组请求.
I need to access the HttpServletRequest
properties to get the javax.servlet.request.X509Certificate which contains the X509Certificate
array of certificates for TLS requests.
从 JAX-RS ContainerRequestFilter
我可以轻松地从 ContainerRequestContext.getProperty(String property)
方法中提取它,但我找不到获取它的方法来自 WebSocket Session
和 HandshakeRequest
,从中我可以访问 HttpSession
实例,但不能访问 HttpServletRequest
实例.
From a JAX-RS ContainerRequestFilter
I can easily extract this from the ContainerRequestContext.getProperty(String property)
method, but I can't find a way to get it from the WebSocket Session
nor the HandshakeRequest
, from which I can access the HttpSession
instance but not the HttpServletRequest
one.
注意:这不是 从 Web Socket @ServerEndpoint 中的 HttpServletRequest 访问 HttpSession 的副本,因为我需要访问 HttpServletRequest
(或等效于提取 TLS 证书),而不是 HttpSession
.
Note: this is not a duplicate of Accessing HttpSession from HttpServletRequest in a Web Socket @ServerEndpoint since I need accesso to the HttpServletRequest
(or equivalent to extract the TLS certificates), not HttpSession
.
由于WebSocket 是HTTP 的超集,我想应该是可能的,希望Java 团队已经想到了一种访问servlet 属性的方法,但我真的找不到.有人知道这是否可能吗?
Since WebSocket is a superset of HTTP, I guess it should be possibile and hope the Java team had thought of a way to access the servlet properties, but I really couldn't find one. Anyone knows if this is possible at all?
推荐答案
无需黑客:
- 在 URL 模式匹配 websocket 握手请求上创建 servlet 过滤器.
- 在过滤器中,获取感兴趣的请求属性并将其放入会话中,然后再继续链.
- 最后从会话中获取它,而会话又可以通过握手请求获得.
与黑客:
- 使用反射在握手请求实例中查找
ServletRequest
字段. 获取其
javax.servlet.request.X509Certificate
属性.
换句话说:
public class ServletAwareConfigurator extends Configurator {
@Override
public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
ServletRequest servletRequest = getField(request, ServletRequest.class);
X509Certificate[] certificates = (X509Certificate[]) servletRequest.getAttribute("javax.servlet.request.X509Certificate");
// ...
}
private static <I, F> F getField(I instance, Class<F> fieldType) {
try {
for (Class<?> type = instance.getClass(); type != Object.class; type = type.getSuperclass()) {
for (Field field : type.getDeclaredFields()) {
if (fieldType.isAssignableFrom(field.getType())) {
field.setAccessible(true);
return (F) field.get(instance);
}
}
}
} catch (Exception e) {
// Handle?
}
return null;
}
}
这篇关于访问 WebSocket @ServerEndpoint 中的 HttpServletRequest 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!