访问WebSocket @ServerEndpoint中的HttpServletRequest属性

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

从JAX-RS ContainerRequestFilter我可以轻松地从ContainerRequestContext.getProperty(String property)方法中提取它,但是我找不到从WebSocket Session获取它的方法,也没有找到HandshakeRequest ,我可以从中访问HttpSession实例但是不是HttpServletRequest之一。

注意:这不是在Web Socket @ServerEndpoint中从HttpServletRequest访问HttpSession的重复,因为我需要访问HttpServletRequest (或等效于提取TLS证书),而不是HttpSession

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

没有黑客攻击:

  1. 在URL模式匹配websocket握手请求上创建servletfilter。
  2. 在filter中,获取感兴趣的请求属性并在继续链之前将其置于会话中。
  3. 最后从会话中获取它,而会话又可通过握手请求获得。

随着黑客行为:

  1. 使用reflection在握手请求实例中查找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  F getField(I instance, Class 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; } }