问题
I need to access the HttpServletRequest
properties to get the javax.servlet.request.X509Certificate which contains the X509Certificate
array of certificates for TLS requests.
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.
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
.
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?
回答1:
Without hacking:
- Create servlet filter on URL pattern matching websocket handshake request.
- In filter, get request attribute of interest and put it in session before continuing chain.
- Finally get it from the session which is in turn just available via handshake request.
With hacking:
- Use reflection to find
ServletRequest
field in handshake request instance. Get its
javax.servlet.request.X509Certificate
attribute.In other words:
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; } }
来源:https://stackoverflow.com/questions/36184382/accessing-httpservletrequest-properties-within-a-websocket-serverendpoint