2013-08-29 10 views
10

Possiedo un'app di Java mostruosa (un client del noto server di applicazioni GNUEnterprise) e la sua origine, che posso compilare dopo aver apportato alcune modifiche. L'app utilizza la rete pesantemente e ho bisogno di monitorare ogni richiesta e risposta. Potrei usare uno sniffer come Wireshark, ma l'applicazione funziona con il suo server su SSL, quindi non conoscendo la chiave privata del certificato SSL qualsiasi traffico sniffato è abbastanza inutile.Registra tutte le interazioni di rete dell'applicazione Java

Cosa posso fare per rendere ogni richiesta e risposta da registrare dall'applicazione stessa? Devo vedere tutte le intestazioni inviate e ricevute. Non voglio modificare tutto il codice responsabile per l'interazione di rete. Quello che voglio è quello di mettere un codice come

Network.setDefaultLogger(myCustomLoggerInstance); 

da qualche parte vicino all'inizio del app e poi nel myCustomLoggerInstance fare tutto la registrazione ho bisogno.

Inoltre, dato che tutte le operazioni di rete sono fatte con URLConnection s, posso ottenere le intestazioni di risposta con con.getHeaderFields() e richiedere le intestazioni con con.getRequestProperties(). Ma perché i cookie non ci sono? Come scaricare i cookie inviati e ricevuti nello stesso modo?

EDIT: Quello che sto cercando di raggiungere è quello di imitare la comunicazione di RPC-applicazione con i suoi server tramite SSL, ad esempio, utilizzando curl. Per questo ho bisogno di ottenere il registro dettagliato del traffico di rete dell'app.

+0

vorrei modificare 'OpenJDK', implementare la funzionalità logger citato poi annusare la comunicazione presso la biblioteca livello. – auselen

+0

@auselen troppo hacky. Se non c'è modo di farlo a livello di applicazione (e sembra così), farò meglio ad attaccare a un server proxy di logging esterno, come suggerito da greyfairer. – Hnatt

risposta

11

Non è possibile utilizzare un server proxy di registrazione, ad es. http://www.charlesproxy.com/ o http://fiddler2.com/? Charles Proxy può anche decodificare le richieste AMF, Fiddler è il campione per l'intercettazione SSL.

IIRC è possibile impostare le proprietà di sistema http.proxyHost e http.proxyPort su 127.0.0.1 e 8888 e java URLConnections si collegherà automaticamente tramite il server proxy di registrazione e si otterrà una buona visualizzazione del proprio traffico HTTP.

Oppure, se l'intenzione è di essere in grado di riprodurre la comunicazione, utilizzare JMeter HTTP Proxy, questo record in un formato adatto per la riproduzione. Ha anche il supporto integrato per la gestione dei cookie.

Se l'applicazione utilizza servizi Web di qualità, SoapUI dispone anche di un proxy di monitoraggio che intercetta le chiamate al servizio Web per cui è stato importato WSDL.

+0

Oh, e ha anche lo sniffing del traffico SSL. Ci proverò sicuramente. – Hnatt

+0

Per consentire SSL Sniffing, è necessario modificare anche il tuo truststore java, vedere: http: // stackoverflow.it/questions/8549749/how-to-capture-https-with-fiddler-in-java – greyfairer

+0

l'app su cui sto lavorando lo gestisce già. Ha una classe che utilizza 'HttpsURLConnection.setDefaultHostnameVerifier' e' .setDefaultSSLSocketFactory' per fidarsi di tutti i certificati. Accetterò la tua risposta se non ci saranno proposte soluzioni a livello di applicazione, perché in realtà fa ciò che voglio, anche se in un modo diverso. Ho anche trovato un'alternativa gratuita a Charles chiamata [webscarab] (https://www.owasp.org/index.php/Category:OWASP_WebScarab_Project), che gira su Linux a differenza di Fiddler. – Hnatt

2

Voglio solo pubblicare uno snippet di codice che è possibile utilizzare al punto di partenza. Non ho un logger "globale" ma con piccole modifiche al codice esistente puoi raggiungere il tuo obiettivo. "Log" sullo standard output, poiché il problema può essere suddiviso in due parti: ottenere le informazioni da UrlConnection e memorizzarle per ulteriori riferimenti.

Questo codice registra la richiesta:

public class URLConnectionReader { 

    public static void main(String[] args) throws Exception { 
    URL oracle = new URL("http://www.google.com/"); 
    URLConnection yc = oracle.openConnection(); 

    String headerName = null; 
    for (int i = 1; (headerName = yc.getHeaderFieldKey(i)) != null; i++) { 
    if (headerName.equals("Set-Cookie")) { 
     String cookie = yc.getHeaderField(i); 
     System.out.println("Cookie :: " + cookie); 
    } else { 
     System.out.println("Header: "+ yc.getHeaderField(i)); 
    } 
    } 

    BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream())); 
    String inputLine; 
    while ((inputLine = in.readLine()) != null) 
    System.out.println(inputLine); 
    in.close(); 
} 

}

salvare tutti questi dati a uno o più file non è difficile. Se ritieni di essere sulla buona strada per il tuo problema, sarei lieto di modificare la risposta con altri dettagli, se necessario.

+0

Grazie, ma sembra che 'getHeaderFieldKey (i)' e 'getHeaders()' per qualche motivo saltino le intestazioni 'Set-Cookie'. Ad ogni modo, sto cercando un modo per impostare un logger di rete globale per l'intera applicazione, senza dover inserire frammenti di codice ovunque avvenga l'interazione di rete. Inoltre, con la tua soluzione devo leggere la connessione due volte. – Hnatt

+0

E, naturalmente, salvare il registro in un file non è un problema. Quindi ho diviso la mia domanda in due parti seguenti: 1) Impostazione del logger globale; 2) Registrazione del traffico senza leggere o inviare risposte e richieste due volte. – Hnatt

+0

Oops, mio ​​male. Se chiami 'getHeaders()' dopo aver inviato una richiesta su un'istanza 'URLConnection', non apre il flusso di lettura la seconda volta, e in effetti puoi vedere le intestazioni di' Set-Cookie' lì. Quindi +1 per te, mi dispiace per tutte le affermazioni sbagliate. Quello che rimane è un modo per impostare il proxy per tutte le connessioni di rete (intendo Proxy modello OOP, non un server proxy). – Hnatt

2

Ho scavato un po 'oltre, e apparentemente, HttpURLConnection viene fornito con java.util.logging abilitato di default.

Vedi questioni connesse: Java: Display request of an HttpURLConnection before sending e How to enable wire logging for a java HttpURLConnection traffic?

java.util.la registrazione era il tentativo (fallito) di Sun di standardizzare i provider di registrazione in Java 1.4. Puoi collegarlo a SLF4J tramite il modulo jul-to-slf4j se vuoi evitare di modificare le proprietà del sistema.

Ma vorrei ancora preferiscono Fiddler o JMeter delega però :-)

+0

Impossibile riuscire a farlo funzionare. Ora preferisco anche un server proxy. – Hnatt

0

Se si desidera registrare il traffico di rete & avete oggetti URLConnection allora il problema è già risolto!
Se si desidera accedere a livello di flusso, è necessario scrivere un piccolo wrapper sopra i flussi I/O & registrare tutti i dati prima di trasferirli su livelli di rete inferiori, altrimenti è possibile utilizzare direttamente gli oggetti di connessione per ottenere le informazioni richieste & registrali.
Per cookie di gestione, è necessario utilizzare java.net.HttpCookie che viene introdotto in Java 6. L'unica cosa che dovete fare è di creare un'istanza di CookieManager & impostarlo come biscotto manager di default:

CookieManager cookieManager = new CookieManager(); 
CookieHandler.setDefault(cookieManager); 

& è possibile utilizzarlo per la gestione dei cookie di connessione!

+0

Originariamente ho cercato qualcosa come questo oggetto gestore cookie globale, solo per tutte le azioni di rete, ma poi ho deciso che utilizzare il server proxy di registrazione locale è sufficiente. In questo caso non ho nemmeno bisogno di interferire con il codice sorgente. A proposito, si può usare il 'CookieManager' personalizzato per registrare le intestazioni delle richieste in entrata e in uscita, non solo i cookie. I metodi 'CookieManager'' get' e 'put' hanno' requestHeaders' e 'responseHeaders' corrispondentemente come loro secondo argomento di tipo' Lista '. Mi chiedo solo se questi metodi vengono chiamati ad ogni richiesta e risposta o solo quando vengono utilizzati i cookie. – Hnatt

9

Un modo rapido per accedere tutto il traffico SSL è per l'avvio java con:

-Djavax.net.debug=all 

o impostarla come una proprietà di sistema:

System.setProperty("javax.net.debug","all"); 

Brace te stesso. Lo standard out diventa rumoroso se lo fai!

(* Nota:.. Registra solo il traffico SSL e SSL informazioni di debug (strette di mano, ecc) prese regolari non vengono registrati)

Problemi correlati