2012-03-21 10 views
5

Ho bisogno di parlare con un server web oscuro che richiede l'autenticazione. Se non fornisco le credenziali, viene visualizzato un modulo di accesso. Tuttavia, se fornisco credenziali di autenticazione di base non richieste, ottengo direttamente il contenuto desiderato.Autenticazione HTTP con componenti Apache HTTP: invio forzato di una sfida

wget supporta questo direttamente:

# this fails and downloads a form: 
wget https://weird.egg/data.txt --http-user=me --http-password=shhh 

# this works and downloads the document: 
wget https://weird.egg/data.txt --http-user=me --http-password=shhh --auth-no-challenge 

Ora la mia domanda: Come posso fare il download in Java utilizzando componenti HTTP di Apache?

Ecco cosa ho ottenuto finora. (C'è anche un proxy a posto, e io uso -Y on in wget, e ho un https_proxy variabile d'ambiente corrispondenza.)

import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.conn.params.ConnRoutePNames; 
import org.apache.http.auth.AuthScope; 
import org.apache.http.auth.UsernamePasswordCredentials; 
import java.net.URI; 

// ... 

DefaultHttpClient hc = new DefaultHttpClient(); 
hc.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, new HttpHost(proxy_name, proxy_port)); 

URI uri = new URI("https://weird.egg/data.txt"); 

hc..getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthScope.ANY_SCHEME), new UsernamePasswordCredentials("me", "shh")); 

hc.execute(new HttpGet(uri)); // etc 

Tuttavia, ho solo alla fine con la pagina del modulo di login, non il documento vero e proprio. Sospetto che DefaultHttpClient non invii le credenziali non richieste, nel modo in cui lo fa wget. C'è un modo per far sì che il programma Java invii le credenziali?

risposta

10

Non importa. Ho risolto il problema, non cercando di utilizzare tutti i metodi di autenticazione biblioteca, ma solo bruta costringendo l'intestazione di autenticazione di base nella richiesta:

HttpGet get = new HttpGet(uri); 

String basic_auth = new String(Base64.encodeBase64((username + ":" + password).getBytes())); 
get.addHeader("Authorization", "Basic " + basic_auth); 

hc.execute(get); // etc 

(questo ha bisogno del supplementare import org.apache.commons.codec.binary.Base64;, ma a sua volta siamo in grado di rimuovere la credential- importazioni correlate)

+0

Ottima idea, grazie. Anche la soluzione quadro non ha funzionato per me. Aggiunta manuale dell'intestazione. –

+0

Grazie. Ho avuto lo stesso problema con il client Maven HTTP Wagon e lo risolvo aggiungendo manualmente l'intestazione. –

+1

al giorno d'oggi puoi semplicemente usare 'java.util.Base64.getEncoder(). EncodeToString (qualcosa)', non c'è bisogno di dipendere da 'import org.apache.commons.codec.binary.Base64;' – eis

Problemi correlati