2014-06-22 10 views
5

Il mio cliente implementa bidirezionale SSL nel seguente modo:getAttribute ("javax.servlet.request.X509Certificate") not set (primavera, CXF, Gettata, JAX-RSv1.1)

 

    private final static String KEYSTORE = "/security/client.jks"; 
    private final static String KEYSTORE_PASSWORD = "secret"; 
    private final static String KEYSTORE_TYPE = "JKS"; 
    private final static String TRUSTSTORE = "/security/certificates.jks"; 
    private final static String TRUSTSTORE_PASSWORD = "secret"; 
    private final static String TRUSTSTORE_TYPE = "JKS"; 
    ... 
    KeyStore keystore = KeyStore.getInstance(KEYSTORE_TYPE); 
    FileInputStream keystoreInput = new FileInputStream(new File(KEYSTORE)); 
    keystore.load(keystoreInput, KEYSTORE_PASSWORD.toCharArray()); 
    KeyStore truststore = KeyStore.getInstance(TRUSTSTORE_TYPE); 
    FileInputStream truststoreIs = new FileInputStream(new File(TRUSTSTORE)); 
    truststore.load(truststoreIs, TRUSTSTORE_PASSWORD.toCharArray()); 
    SSLSocketFactory socketFactory = new SSLSocketFactory(keystore, KEYSTORE_PASSWORD, truststore); 
    Scheme scheme = new Scheme("https", 8543, socketFactory); 
    SchemeRegistry registry = new SchemeRegistry(); 
    registry.register(scheme); 
    ClientConnectionManager ccm = new PoolingClientConnectionManager(registry); 
    httpclient = new DefaultHttpClient(ccm); 
    HttpResponse response = null; 
    HttpGet httpget = new HttpGet("https://mylocalhost.com:8543/test"); 
    response = httpclient.execute(httpget); 
    ... 

E Provo a recuperare il certificato X.509 dal lato del server dal client tramite javax.servlet.http.HttpServletRequest.getAttribute ("javax.servlet.request.X509Certificate") come descritto qui: http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletRequest.html#getAttribute%28java.lang.String%29.

ottengo il HttpServletRequest dalla parte del server tramite:
HttpServletRequest ServletRequest = (HttpServletRequest) msg.get ("HTTP.REQUEST"); tramite il metodo handleMessage (Message msg) della mia classe interceptor che estende AbstractPhaseInterceptor <Message>. Devo usare JAX-RS 1.1.1 dal lato del server a causa di alcune dipendenze Maven che non posso modificare e quindi non posso usare ContainerRequestFilter (supportato da JAX-RS 2.0 su).

Il mio problema è che getAttribute ("javax.servlet.request.X509Certificate") sul lato server restituisce null sempre. Se verifichi il traffico tra server e client, posso vedere che il certificato dal server viene inviato al client, che funziona con l'handshake. Ma non riesco a vedere che il certificato del client viene inviato al server e penso che sia il motivo per cui getAttribute("javax.servlet.request.X509Certificate") restituisce null. Qualcuno sa come posso risolvere questo problema? Ho già provato altre implementazioni dal lato del cliente, ma senza modifiche.

Cosa sto sbagliando? Molte grazie in anticipo!

Ulteriori informazioni: Ho visto sul lato del server che javax.servlet.request.ssl_session_id, javax.servlet.request.key_size e javax.servlet.request.cipher_suite sono impostati, ma la javax.servlet.request chiave. X509Certificate non è impostato. Sto usando Jetty Server 8.1.15, Apache CXF 2.7.x e JAX-RS 1.1.1. Ho provato con la configurazione di Jetty tramite http://cxf.apache.org/docs/jetty-configuration.html e http://cxf.apache.org/docs/secure-jax-rs-services.html#SecureJAX-RSServices-Configuringendpoints, l'attributo non è ancora impostato.

+0

Il titolo suggerisce di voler firmare la richiesta HTTPS, il contenuto della domanda sembra che tu stia cercando di utilizzare un certificato client. Quelle sono cose diverse. – Bruno

+0

Ciao Bruno, un cliente deve essere autenticato dal server tramite certificato X.509. Voglio estrarre il certificato X.509 in modo che il server possa confrontare il certificato con il suo truststore. Non ho ancora potuto scoprire se il problema è dal lato del cliente o dal lato del server. Quindi la mia domanda potrebbe essere un po 'aspecifica. Per favore, sopportami, sono un principiante qui. Grazie molto! Ho aggiunto ulteriori informazioni sopra. –

risposta

13

Il problema è risolto. Non era un problema nel codice, era solo un problema di certificato. Il mio problema era che ero un principiante per quanto riguarda i certificati X509, era un problema di stretta di mano tra server e client. In questo caso, solo il debug SSL/Handshake mi ha aiutato. Il log di debug indicava che il server accettava solo i certificati client da una CA specifica, il server comunicava al client la CA richiesta in una richiesta di certificato durante il messaggio ServerHello. Poiché il client non aveva un certificato da tale CA, non ha inviato alcunché e la connessione tra client e server è stata chiusa, con il risultato che javax.servlet.request.X509Certificate non è stato impostato.

Per tutti gli altri che potrebbero aderire lo stesso problema qualche tempo (che sembra essere un problema di configurazione comune SSL per quanto riguarda ad IBM come è menzionato nel primo link sotto), le seguenti fonti mi ha aiutato molto:
- http://www-01.ibm.com/support/docview.wss?uid=swg27038122&aid=1 (pagine 16 e 17)
- http://java.dzone.com/articles/how-analyze-java-ssl-errors (spettacoli come la stretta di mano dovrebbe guardare)
- need help Debugging SSL handshake in tomcat (mostra come eseguire il debug errori SSL in Java)
- https://thomas-leister.de/internet/eigene-openssl-certificate-authority-ca-erstellen-und-zertifikate-signieren/ (in tedesco, ma forse si può trovare un equivalente inglese)
- https://access.redhat.com/site/documentation/en-US/Red_Hat_JBoss_Fuse/6.0/html/Web_Services_Security_Guide/files/i382674.html (continuazione dell'arte tedesca icolo)
- http://www.webfarmr.eu/2010/04/import-pkcs12-private-keys-into-jks-keystores-using-java-keytool/ (come creare keystore e truststore)

Dopo aver creato una propria CA, un certificato di server e client e dopo aver creato il keystore e truststore per entrambi, l'attributo è stato fissato oggi:
- Here15_1: javax.servlet.request.X509Certificate
- Here16_2: class [Ljava.security.cert.X509Certificate;
- Here16_3: [Ljava.security.cert.X509Certificate; @ 43b8f002
Il codice server è in grado di estrarre anche le informazioni sul certificato client.

+0

Nota: Devo aggiungere che "javax.net.ssl.SSLHandshakeException: catena di cert null" viene lanciata dal server solo se i flag ... ... e ... ... sono impostati su true dal lato del server. Se needClientAuth è impostato su false, il client e il server non generano messaggi di errore poiché il certificato client non è richiesto. –

Problemi correlati