Hai bisogno di aiuto per creare l'autenticazione del digest per Android
android-asynctask digest-authentication (2)
La versione di HttpClient
di Apache fornita con Android si basa su una vecchia versione pre-BETA di HttpClient
. Google ha da tempo consigliato di non utilizzarlo e rimuoverlo in Android 6.0 . HttpURLConnection
sostitutivo di Google non supporta l'autenticazione del digest HTTP , ma solo di base.
Questo ti lascia alcune opzioni, tra cui:
-
HttpURLConnection
aHttpURLConnection
(come consiglia Google) e utilizza una libreria, bare-bones-digest , per l'autenticazione digest. Esempio di seguito. - Utilizzare la libreria OkHttp invece di
HttpURLConnection
oHttpClient
. OkHttp non supporta il digest out of the box, ma c'è una libreria okhttp-digest che implementa un digest authentic. Esempio di seguito. - Continua a utilizzare
HttpClient
(deprecato) aggiungendo esplicitamente la libreria'org.apache.http.legacy'
alla tua build, come menzionato nella lista delle modifiche per Android 6.0 . - Esiste un progetto Apache per il porting di versioni più recenti di
HttpClient
ad Android, ma il progetto è stato interrotto. Maggiori informazioni sulla pagina di Apache su HttpClient per Android . - Implementa il digest HTTP tu stesso.
Ecco un esempio dettagliato di come autenticare una richiesta usando bare-bones-digest e HttpURLConnection
(copiata dalla pagina github del progetto):
// Step 1. Create the connection
URL url = new URL("http://httpbin.org/digest-auth/auth/user/passwd");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Step 2. Make the request and check to see if the response contains
// an authorization challenge
if (connection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) {
// Step 3. Create a authentication object from the challenge...
DigestAuthentication auth = DigestAuthentication.fromResponse(connection);
// ...with correct credentials
auth.username("user").password("passwd");
// Step 4 (Optional). Check if the challenge was a digest
// challenge of a supported type
if (!auth.canRespond()) {
// No digest challenge or a challenge of an unsupported
// type - do something else or fail
return;
}
// Step 5. Create a new connection, identical to the original
// one..
connection = (HttpURLConnection) url.openConnection();
// ...and set the Authorization header on the request, with the
// challenge response
connection.setRequestProperty(
DigestChallengeResponse.HTTP_HEADER_AUTHORIZATION,
auth.getAuthorizationForRequest("GET", connection.getURL().getPath()));
}
Ecco un esempio di OkHttp e okhttp-digest (copiato dalla pagina okhttp-digest):
client = new OkHttpClient();
final DigestAuthenticator authenticator = new DigestAuthenticator(new Credentials("username", "pass"));
final Map<String, CachingAuthenticator> authCache = new ConcurrentHashMap<>();
client.interceptors().add(new AuthenticationCacheInterceptor(authCache));
client.setAuthenticator(new CachingAuthenticatorDecorator(authenticator, authCache));
Request request = new Request.Builder()
.url(url);
.get()
.build();
Response response = client.newCall(request).execute();
https://code.i-harness.com
Ho questo codice finora:
private class DownloadWebPageTask extends AsyncTask<String, Void, String>
{
@Override
protected String doInBackground(String... theParams)
{
String myUrl = theParams[0];
String myEmail = theParams[1];
String myPassword = theParams[2];
HttpPost post = new HttpPost(myUrl);
post.addHeader("Authorization","Basic "+ Base64.encodeToString((myEmail+":"+myPassword).getBytes(), 0 ));
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String response = null;
try
{
response = client.execute(post, responseHandler);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(
new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null)
{
response += s;
}
}
catch (Exception e)
{
e.printStackTrace();
}
return response;
}
@Override
protected void onPostExecute(String result)
{
}
}
Questo codice non viene compilato perché sono in confusione al punto di:
response = client.execute(post, responseHandler);
InputStream content = execute.getEntity().getContent();
Ho capito che il codice armeggiava con vari esempi, e non ero sicuro di quale Object si supponesse essere il client, e se la prima linea mi avrebbe appena ottenuto la risposta del server, o devo andare per ottenere l'InputStream e leggere il server risposta in?
Per favore aiutami a capire come farlo correttamente.
Grazie!
Potresti voler passare a HttpURLConnection
. Secondo questo articolo la sua API è più semplice di HttpClient
di HttpClient
ed è meglio supportata su Android. Se scegli di andare con HttpURLConnection
, l'autenticazione è piuttosto semplice:
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password".toCharArray());
}
});
Successivamente, continuare a utilizzare HttpURLConnection
come al solito. Un semplice esempio:
final URL url = new URL("http://example.com/");
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
final InputStream is = conn.getInputStream();
final byte[] buffer = new byte[8196];
int readCount;
final StringBuilder builder = new StringBuilder();
while ((readCount = is.read(buffer)) > -1) {
builder.append(new String(buffer, 0, readCount));
}
final String response = builder.toString();