访问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属性的方法,但我真的找不到。 任何人都知道这是否可行?
没有黑客攻击:
- 在URL模式匹配websocket握手请求上创建servletfilter。
- 在filter中,获取感兴趣的请求属性并在继续链之前将其置于会话中。
- 最后从会话中获取它,而会话又可通过握手请求获得。
随着黑客行为:
- 使用reflection在握手请求实例中查找
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 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; } }