访问 WebSocket @ServerEndpoint 中的 HttpServletRequest 属性

Gio*_*ato 1 java servlets websocket java-websocket jakarta-ee

我需要访问HttpServletRequest属性以获取包含TLS 请求的证书数组的javax.servlet.request.X509CertificateX509Certificate

从 JAX-RSContainerRequestFilter我可以轻松地从ContainerRequestContext.getProperty(String property)方法中提取它,但是我找不到从 WebSocketSession或 中获取它的方法HandshakeRequest,从中我可以访问HttpSession实例但不能访问实例HttpServletRequest

注意:这不是Accessing HttpSession from HttpServletRequest in a Web Socket @ServerEndpoint因为我需要访问HttpServletRequest(或等效于提取 TLS 证书),而不是HttpSession.

由于 WebSocket 是 HTTP 的超集,我想它应该是可能的,希望 Java 团队已经想到了一种访问 servlet 属性的方法,但我真的找不到。任何人都知道这是否可能?

Bal*_*usC 5

没有黑客攻击:

  1. 在 URL 模式匹配 websocket 握手请求上创建 servlet 过滤器。
  2. 在过滤器中,获取感兴趣的请求属性并将其放入会话中,然后再继续链。
  3. 最后从会话中获取它,而会话又可以通过握手请求获得。

与黑客:

  1. 使用反射ServletRequest在握手请求实例中查找字段。
  2. 获取它的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;
        }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)