Reputation: 2273
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?
Upvotes: 3
Views: 3495
Reputation: 1108782
Without hacking:
With hacking:
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;
}
}
Upvotes: 6