访问WebSocket @ServerEndpoint

时间:2016-03-23 17:02:08

标签: java servlets java-ee websocket java-websocket

我需要访问HttpServletRequest属性以获取 javax.servlet.request.X509Certificate ,其中包含用于TLS请求的X509Certificate证书数组。

从JAX-RS ContainerRequestFilter我可以轻松地从ContainerRequestContext.getProperty(String property)方法中提取它,但我找不到从WebSocket Session获取它的方法,也不能找到{{ 1}},我可以从中访问HandshakeRequest个实例,但不能访问HttpSession个实例。

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

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

1 个答案:

答案 0 :(得分:2)

没有黑客攻击:

  1. 在匹配websocket握手请求的URL模式上创建servlet过滤器。
  2. 在过滤器中,获取感兴趣的请求属性并在继续链之前将其置于会话中。
  3. 最后从会话中获取它,而会话又是通过握手请求提供的。
  4. 黑客攻击:

    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;
          }
      
      }