2012-06-07 17 views
16

Abbiamo bisogno di implementare SSL bidirezionale su Google App Engine, dove inviamo richieste di servizi Web utilizzando JAX-WS a un server che richiede l'autenticazione SSL a 2 vie.SSL bidirezionale per servizi Web su GAE (java)

Come possiamo impostare SSL a 2 vie per le nostre richieste di servizi Web in uscita?

Sappiamo che javax.net.ssl* è vietato nell'ambiente App Engine.

Ecco un esempio del nostro codice:

@WebService(name="ListenerSoap", targetNamespace = "http://example.com/Listener.Wsdl") 
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE) 
public interface ListenerSoap { 

    @WebMethod(operationName = "Ping", action="http://example.com/Listener.Wsdl#Ping") 
    public void ping(); 
} 

@WebServiceClient(name="Listener", targetNamespace="http://example.com/Listener.Wsdl", wsdlLocation = "https://example.com/Listener.asmx?WSDL") 
public class Listener extends Service 
{ 
    public ListenerSoap getListenerSoap() { 
    return super.getPort(new QName("http://example.com/Listener.Wsdl", 
         "ListenerSoap"), ListenerSoap.class); 
    } 
} 

e un esempio di codice di cui sopra in uso:

ListenerSoap soap = new Listener().getListenerSoap(); 
soap.ping(); 

immagino che possiamo memorizzare i keystore o qualsiasi certs necessari il DataStore come oggetti binari (anche se il modo di caricarli è ancora un po 'vago per me).

Come possiamo impostare i valori necessari necessari per questo servizio Web per l'autenticazione tramite SSL a 2 vie?

Grazie per qualsiasi aiuto

Aggiornamento:

Attraverso la ricerca che ho visto questo è come può essere fatto su un server tradizionale (una con accesso filesystem):

ListenerSoap soap = new Listener().getListenerSoap(); 
((BindingProvider) soap).getRequestContext().put("javax.net.ssl.keyStore", "client_cert.p12" 

Tuttavia, in questo approccio, è previsto che client_cert.p12 si trovi nel file system.

Inoltre, SSLSocketFactory, SSLContext, KeyManager e KeyManagerFactory non sono consentiti su GAE.

Aggiornamento:

partire dalla GAE SDK versione 1.7.7. questo dovrebbe essere possibile:

Similarly, Java developers can now use the javax.net.ssl package to make outbound SSL connections. 

GAE 1.7.7 SDK Release Notes

+6

C'è una richiesta di funzionalità aperta per il supporto dei certificati client nel servizio URLFetch: http://code.google.com/p/googleappengine/issues/detail?id=3719 –

risposta

0

Per quello che so di due vie SSL, si avrà alcun legame con il codice di Java EE: a due vie SSL è un Transport Layer Security: quando l'applicazione client proverà a creare una connessione HTTP protetta (HTTPS) con il servizio, il server chiederà un certificato e approverà o meno questo certificato. Se il certificato client è stato approvato, verrà stabilita una connessione protetta per le parti e saranno autorizzati a scambiare alcuni messaggi attraverso questo tunnel. Ma questo processo è fatto sul livello di trasporto. Il tuo codice (sul livello dell'applicazione) non verrà mai informato di questo processo. Per stabilire SSL a due vie, la configurazione viene eseguita sull'installazione del server delle applicazioni per la porta SSL.

+4

Questo non è assolutamente vero. È completamente possibile stabilire una connessione SSL bidirezionale tramite il codice dell'applicazione, come ad esempio l'impostazione 'systemProps.put (" javax.net.ssl.keyStore ", keyStorePath);' per esempio. Il problema è che GAE annota i pacchetti 'java.net.ssl ​​*' e quindi è impossibile farlo su GAE al momento della scrittura per questo motivo. – Cuga

+0

dovrei ammettere che ho sbagliato. Ecco un codice sammple su come implementare SSL bidirezionale in un codice java: https://sites.google.com/site/ssljavaguide/example-code/2-way-ssl – omartin

+0

Che ancora non funzionerà su GAE perché tutto le classi sono nella lista nera sotto i pacchetti 'javax.net.ssl. *', tra cui 'SSLSocket' e' SSLSocketFactory' – Cuga

1
ListenerSoap soap = new Listener().getListenerSoap(); 

spero che migliora

Grazie

+0

Sì, questo è anche incluso nel post ... la domanda è come ottenere SSL a 2 vie lavorando su GAE- - un'attività che sembra non fattibile. – Cuga

1

So che potrebbe non voler sentire questo, ma utilizzando SSL è costoso e problematico per la comunicazione a due vie.A seconda della quantità di controllo che si ha sul server/client, preferisco un tubo bidirezionale semplice come socket web e un protocollo di pacchetto dati che può semplicemente implementare AES. Dipende davvero dal problema che stai cercando di risolvere.

+2

Penso che l'OP stia parlando dell'autorizzazione bidirezionale * (autenticazione, in realtà). –

+0

e una volta autenticato? –

+1

La * comunicazione * è sicura in entrambe le direzioni; le chiavi pubbliche/private vengono utilizzate per scambiare le chiavi simmetriche che entrambe le parti utilizzano per la crittografia. Questa domanda riguarda l'uso di un certificato su * entrambi * il client * e * server, per autenticarsi l'uno con l'altro. –

1

Sembra che ci sia confusione sulla semplice connessione tramite SSL (https://...) e ciò che è noto come "autenticazione reciproca" o "infrastruttura a chiave pubblica (PKI)". Puoi effettivamente fare entrambi o uno indipendentemente dall'altro. Con quest'ultimo (quello a cui penso si riferisca la domanda originale), quando si effettua una richiesta al server, il server risponderà chiedendo un certificato che è necessario presentare per autenticarsi.

Per rispondere alla domanda specifica sopra (caricamento di un keystore da dati binari), non penso che sia realmente possibile, dal momento che è il runtime Java che viene prelevato sul vostro keystore. L'unico pensiero che potresti fare è caricare i bit dal tuo datastore e scriverlo temporaneamente su disco. Opzionalmente eliminarlo quando esiste l'applicazione. Questo l'ho già fatto e funziona abbastanza bene. Se si esegue questa operazione, mi consiglia di utilizzare una posizione probabile che sia scrivibile (come System.getProperty("java.io.tmpdir"));), quindi dopo aver scritto il file su disco, impostare le proprietà JVM (ad es System.getProperties().put("javax.net.ssl.keyStore","...");)

+0

L'altra opzione (se non è possibile scrivere su disco o utilizzare javax.net.ssl. *) è fare la connessione manualmente (cioè utilizzando Apache HTTP Client), per aggiungi un keystore. Quindi devi semplicemente regolare il POST HTTP all'endpoint e analizzare la risposta. Vedi: http://stackoverflow.com/questions/5206010/using-apache-httpclient-for-https –

+0

Come menzionato nell'aggiornamento al post originale, non è possibile impostare 'javax.net.ssl' su GAE a causa di una lista nera di quei pacchetti. Inoltre, non è possibile scrivere su qualsiasi disco di file. Abbiamo configurato PKI su altri server che lo utilizzano, ma GAE non lo consentirà. – Cuga

+0

Capito. Non sono molto familiare con GAE. Sembra che la tua unica scelta sia quella di non utilizzare il codice JAX-WS, piuttosto di usare qualcosa di un livello inferiore come Apache HTTPClient in cui puoi impostare tutte le informazioni di sicurezza. Non è bello, ma ho usato qualcosa come Velocity per creare un modello di messaggio SOAP e usare Apache HC per inviarlo al server. Il lato negativo è che devi analizzare la risposta manualmente (nessuna mappatura POJO di fantasia che otterresti con il codice generato da JAX-WS). –

2

Dalla mia conoscenza limitata circa l'autorizzazione SSL, sembra si può mancare qualcosa di vitale importanza qui; i certificati. SSL bidirezionale richiede che i certificati client e server siano nel tuo keystore, che può essere un certificato autofirmato (un file pkcs12 o pem, che puoi facilmente generare con alcuni comandi tramite shell) o un certificato proprietario emesso da una società autorizzata come Thawte o Verisign. Anche se non sono sicuro se questo è il problema che stai affrontando, ma è bene verificarlo. (Inoltre, sono un principiante quindi per favore non invertire la mia risposta, solo cercando di suggerire possibili opzioni.)

+1

Grazie. Abbiamo tutte le chiavi e i certificati. Il problema era riuscire a fornire i certificati nell'ambiente GAE, cosa che al momento non era possibile, ma oggi sembra che sarebbe possibile con le whitelist recenti da parte di Google. – Cuga

1

SSL a 2 vie (dall'app ospitata in GAE al mondo esterno) non è supportato per quanto mi riguarda conoscere. Ho provato un'app di esempio pochi mesi fa ed ero frustrato nel constatare che GAE non supportava nemmeno questa funzione di base .. e anche le documentazioni non sono chiare. Non sarà possibile presentare il certificato cliente quando si contatta un servizio Web. Non è possibile archiviarlo, non è possibile accedere al keystore.

+0

Non l'ho ancora provato, ma a partire da GAE SDK v1.7.7 potrebbe essere possibile farlo ora, dato che hanno autorizzato i pacchetti 'javax.net.ssl', che ora dovrebbero permetterci di specificare il cert via '((BindingProvider) soap) .getRequestContext(). Put (" javax.net.ssl.keyStore "...' – Cuga