2017-08-20 120 views
1

ServerEndpointはWildFly 10で動作します。これは相互のTLSを使用してwssに設定されているため、クライアント証明書が必要です。私はエンドポイントへの接続に問題はないので、相互認証は正しく行われますが、onOpenメソッドでクライアント証明書にアクセスすることはできません。私はgetUserPrincipal()を使ってそれをしようとしています、私はいつもnullを得ています。WebSocketサーバーでクライアント証明書を取得します。

認証目的でクライアント証明書を取得する必要があります。

import java.io.IOException; 
import java.security.Principal; 

import javax.servlet.http.HttpSession; 
import javax.websocket.EndpointConfig; 
import javax.websocket.OnClose; 
import javax.websocket.OnMessage; 
import javax.websocket.OnOpen; 
import javax.websocket.Session; 
import javax.websocket.server.ServerEndpoint; 

@ServerEndpoint(value = "/test", configurator = GetHttpSessionConfigurator.class) 
public class TestWebSocketEndPoint { 

    private Session wsSession; 
    private HttpSession httpSession; 

    @OnOpen 
    public void onOpen(Session session, EndpointConfig config){ 
     this.wsSession = session; 
     this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName()); 
     Principal userPrincipal = session.getUserPrincipal(); 
     System.out.println(session.getId() + " has opened a connection"); 
     try { 
      session.getBasicRemote().sendText("Connection Established"); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 
    } 

    /** 
    * When a user sends a message to the server, this method will intercept the message 
    * and allow us to react to it. For now the message is read as a String. 
    */ 
    @OnMessage 
    public void onMessage(String message, Session session){ 
     System.out.println("Message from " + session.getId() + ": " + message); 
     try { 
      session.getBasicRemote().sendText(message); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 
    } 

    /** 
    * The user closes the connection. 
    * 
    * Note: you can't send messages to the client from this method 
    */ 
    @OnClose 
    public void onClose(Session session){ 
     System.out.println("Session " +session.getId()+" has ended"); 
    } 
} 

GetHttpSessionConfigurator:

import java.security.Principal; 
import java.util.List; 
import java.util.Map; 

import javax.servlet.http.HttpSession; 
import javax.websocket.HandshakeResponse; 
import javax.websocket.server.HandshakeRequest; 
import javax.websocket.server.ServerEndpointConfig; 

public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator { 
    @Override 
    public void modifyHandshake(ServerEndpointConfig config, 
           HandshakeRequest request, 
           HandshakeResponse response) 
    { 
     HttpSession httpSession = (HttpSession)request.getHttpSession(); 
     Map<String, List<String>> map = request.getParameterMap(); 
     Principal principal = request.getUserPrincipal(); 
     config.getUserProperties().put(HttpSession.class.getName(),httpSession); 
    } 
} 

RequestListener:

import java.security.Principal; 
import java.security.cert.X509Certificate; 

import javax.servlet.ServletRequestEvent; 
import javax.servlet.ServletRequestListener; 
import javax.servlet.annotation.WebListener; 
import javax.servlet.http.HttpServletRequest; 

@WebListener 
public class RequestListener implements ServletRequestListener { 

    public void requestDestroyed(ServletRequestEvent sre) { 
     // TODO Auto-generated method stub 

    } 

    public void requestInitialized(ServletRequestEvent sre) { 
     ((HttpServletRequest) sre.getServletRequest()).getSession(); 
     Principal p = ((HttpServletRequest) sre.getServletRequest()).getUserPrincipal(); 

     boolean secure = ((HttpServletRequest) sre.getServletRequest()).isSecure(); 
     String authType = ((HttpServletRequest) sre.getServletRequest()).getAuthType(); 

     X509Certificate[] certs = (X509Certificate[]) ((HttpServletRequest) sre.getServletRequest()).getAttribute("javax.servlet.request.X509Certificate"); 
    } 

} 

のWebSocketクライアントがTooTallNate/JavaベースのWebSocketと安全接続を使用してスタンドアロンアプリケーションである:

import java.io.BufferedReader; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.URI; 
import java.net.URISyntaxException; 
import java.security.KeyManagementException; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.SecureRandom; 
import java.security.UnrecoverableKeyException; 
import java.security.cert.Certificate; 
import java.security.cert.CertificateException; 
import java.util.Enumeration; 

import javax.net.ssl.KeyManager; 
import javax.net.ssl.KeyManagerFactory; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.SSLSocketFactory; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.TrustManagerFactory; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.java_websocket.WebSocketImpl; 

public class TestClient { 

    private static final Log log = LogFactory.getLog(TestClient.class); 

    public static void main(String[] args) throws URISyntaxException { 
     WebSocketImpl.DEBUG = true; 

     WSRAClient wsRaClient = new WSRAClient(new URI("wss://localhost:8443/TestWebSocket-0.0.1-SNAPSHOT/test")); 

     String keystoreFile = "keystore.p12"; 
     String keystorePassword = "keystore"; 

     String truststoreFile = "truststore.jks"; 
     String truststorePassword = "truststore"; 


     try { 
      SSLContext ssl = SSLContext.getInstance("TLSv1.2"); 

      log.info("Configuring SSL keystore"); 
      KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
      KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType()); 
      log.debug("Loading keystore"); 
      store.load(new FileInputStream(keystoreFile), keystorePassword.toCharArray()); 
      log.debug("Number of keystore certificates: " + store.size()); 
      Enumeration<String> enumeration = store.aliases(); 
      while(enumeration.hasMoreElements()) { 
       String alias = enumeration.nextElement(); 
       log.debug("alias name: " + alias); 
       Certificate certificate = store.getCertificate(alias); 
       log.debug(certificate.toString()); 
      } 
      kmf.init(store, keystorePassword.toCharArray()); 
      KeyManager[] keyManagers = new KeyManager[1]; 
      keyManagers = kmf.getKeyManagers(); 

      log.info("Configuring SSL truststore"); 
      TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
      KeyStore truststore = KeyStore.getInstance(KeyStore.getDefaultType()); 
      log.debug("Loading truststore"); 
      truststore.load(new FileInputStream(truststoreFile), truststorePassword.toCharArray()); 
      log.debug("Number of truststore certificates: " + truststore.size()); 
      enumeration = truststore.aliases(); 
      while(enumeration.hasMoreElements()) { 
       String alias = (String)enumeration.nextElement(); 
       log.debug("alias name: " + alias); 
       Certificate certificate = truststore.getCertificate(alias); 
       log.debug(certificate.toString()); 
      } 
      tmf.init(truststore); 
      TrustManager[] trustManagers = tmf.getTrustManagers(); 

      ssl.init(keyManagers, trustManagers, new SecureRandom()); 

      SSLSocketFactory factory = ssl.getSocketFactory();// (SSLSocketFactory) SSLSocketFactory.getDefault(); 

      wsRaClient.setSocket(factory.createSocket()); 

      wsRaClient.connectBlocking(); 

      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 
      while (true) { 
       String line = reader.readLine(); 
       if(line.equals("close")) { 
        wsRaClient.close(); 
       } else { 
        wsRaClient.send(line); 
       } 
      } 

     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
      log.error(e); 
      System.exit(0); 
     } catch (KeyStoreException e) { 
      e.printStackTrace(); 
      log.error(e); 
      System.exit(0); 
     } catch (CertificateException e) { 
      e.printStackTrace(); 
      log.error(e); 
      System.exit(0); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
      log.error(e); 
      System.exit(0); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      log.error(e); 
      System.exit(0); 
     } catch (UnrecoverableKeyException e) { 
      e.printStackTrace(); 
      log.error(e); 
      System.exit(0); 
     } catch (KeyManagementException e) { 
      e.printStackTrace(); 
      log.error(e); 
      System.exit(0); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
      log.error(e); 
      System.exit(0); 
     } 

    } 

} 

答えて

1

を参照してください:Accessing HttpServletRequest properties within a WebSocket @ServerEndpoint

  1. のWebSocketハンドシェイクの要求に合致するURLパターンのサーブレットフィルタを作成します。
  2. フィルタでは、関心のあるリクエスト属性を取得し、連鎖を続ける前にセッションに入れます。
  3. 最後に握手要求
を経て今度はちょうど利用できるセッションからそれを得ます
関連する問題