2016-03-23 16 views
1

Ich brauche die HttpServletRequest Eigenschaften für den Zugriff auf die javax.servlet.request.X509Certificate zu erhalten, die die X509Certificate Array von Zertifikaten für TLS-Anforderungen enthält.Zugriff HttpServletRequest Eigenschaften innerhalb einer WebSocket @ServerEndpoint

Von einer JAX-RS ContainerRequestFilter ich dies aus dem ContainerRequestContext.getProperty(String property) Verfahren leicht extrahieren kann, aber ich kann es aus der WebSocket nicht einen Weg finden, um Session noch die HandshakeRequest, von dem mir die HttpSession Instanz zugreifen kann, nicht aber die HttpServletRequest eins.

Hinweis: Dies ist kein Duplikat von Accessing HttpSession from HttpServletRequest in a Web Socket @ServerEndpoint da ich accesso zum HttpServletRequest muß (oder gleichwertig die TLS-Zertifikate zu extrahieren), nicht HttpSession.

Da WebSocket eine Obermenge von HTTP ist, denke ich, es sollte möglich sein und hoffen, dass das Java-Team über einen Weg zum Zugriff auf die Servlet-Eigenschaften gedacht hatte, aber ich konnte wirklich keinen finden. Weiß jemand, ob das überhaupt möglich ist?

Antwort

2

Ohne Hacking:

  1. erstellen Servlet-Filter auf URL-Muster websocket Handshake-Anforderung entsprechen.
  2. Im Filter, erhalten Anfrage Attribut von Interesse und setzen Sie es in Sitzung vor dem Fortfahren Kette.
  3. Schließlich erhalten Sie es aus der Sitzung, die wiederum nur per Handshake-Anfrage verfügbar ist.

Mit Hacking:

  1. Verwenden Reflexion ServletRequest Feld in Handshake-Anforderung Instanz zu finden.
  2. Holen Sie sich javax.servlet.request.X509Certificate Attribut.

    Mit anderen Worten:

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

Sie @BalusC danken, könnte dies funktionieren. Ich würde lieber nicht 'HttpSession' verwenden, wenn möglich. Ich frage mich, ob WebSocket tatsächlich 'HttpServeltRequest' verwendet und es einfach nicht in seiner API verfügbar macht oder überhaupt nicht verwendet ... –

+0

Es ist implementierungsspezifisch. Das ist genau warum "ohne Hacking" :) – BalusC

+0

Sie haben Recht! Ich bin auf WildFly/Undertow übrigens. Wenn der WebSocket JSR "javax.servlet.http.HttpSession" in der "HandshakeRequest" API offen legt, sehe ich wirklich nicht, warum es 'javax.servlet.http.HttpServletRequest' nicht freigibt ... –

Verwandte Themen