Autenticazione di base HttpClient

1. Panoramica

Questo tutorial illustrerà come configurare l'autenticazione di base su Apache HttpClient 4 .

Se vuoi approfondire e imparare altre cose interessanti che puoi fare con HttpClient, vai al tutorial principale di HttpClient .

2. Autenticazione di base con l'API

Cominciamo con il modo standard di configurare l'autenticazione di base su HttpClient, tramite un CredentialsProvider :

CredentialsProvider provider = new BasicCredentialsProvider(); UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("user1", "user1Pass"); provider.setCredentials(AuthScope.ANY, credentials); HttpClient client = HttpClientBuilder.create() .setDefaultCredentialsProvider(provider) .build(); HttpResponse response = client.execute( new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION)); int statusCode = response.getStatusLine() .getStatusCode(); assertThat(statusCode, equalTo(HttpStatus.SC_OK));

Come possiamo vedere, creare il client con un provider di credenziali per configurarlo con l'autenticazione di base non è difficile.

Ora, per capire cosa farà effettivamente HttpClient dietro le quinte, dovremo guardare i log:

# ... request is sent with no credentials [main] DEBUG ... - Authentication required [main] DEBUG ... - localhost:8080 requested authentication [main] DEBUG ... - Authentication schemes in the order of preference: [negotiate, Kerberos, NTLM, Digest, Basic] [main] DEBUG ... - Challenge for negotiate authentication scheme not available [main] DEBUG ... - Challenge for Kerberos authentication scheme not available [main] DEBUG ... - Challenge for NTLM authentication scheme not available [main] DEBUG ... - Challenge for Digest authentication scheme not available [main] DEBUG ... - Selected authentication options: [BASIC] # ... the request is sent again - with credentials

L'intera comunicazione client-server è ora chiara :

  • il client invia la richiesta HTTP senza credenziali
  • il Server rispedisce una sfida
  • il Cliente negozia e identifica il giusto schema di autenticazione
  • il Cliente invia una seconda richiesta , questa volta con le credenziali

3. Autenticazione di base preventiva

Per impostazione predefinita , HttpClient non esegue l'autenticazione preventiva. Invece, questa deve essere una decisione esplicita presa dal cliente.

Innanzitutto, dobbiamo creare HttpContext , pre-popolandolo con una cache di autenticazione con il giusto tipo di schema di autenticazione preselezionato. Ciò significa che la negoziazione dell'esempio precedente non è più necessaria: l' autenticazione di base è già stata scelta :

HttpHost targetHost = new HttpHost("localhost", 8082, "http"); CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS)); AuthCache authCache = new BasicAuthCache(); authCache.put(targetHost, new BasicScheme()); // Add AuthCache to the execution context HttpClientContext context = HttpClientContext.create(); context.setCredentialsProvider(credsProvider); context.setAuthCache(authCache);

Ora possiamo utilizzare il client con il nuovo contesto e inviare la richiesta di pre-autenticazione :

HttpClient client = HttpClientBuilder.create().build(); response = client.execute( new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION), context); int statusCode = response.getStatusLine().getStatusCode(); assertThat(statusCode, equalTo(HttpStatus.SC_OK));

Diamo un'occhiata ai log:

[main] DEBUG ... - Re-using cached 'basic' auth scheme for //localhost:8082 [main] DEBUG ... - Executing request GET /spring-security-rest-basic-auth/api/foos/1 HTTP/1.1 [main] DEBUG ... >> GET /spring-security-rest-basic-auth/api/foos/1 HTTP/1.1 [main] DEBUG ... >> Host: localhost:8082 [main] DEBUG ... >> Authorization: Basic dXNlcjE6dXNlcjFQYXNz [main] DEBUG ... << HTTP/1.1 200 OK [main] DEBUG ... - Authentication succeeded

Tutto sembra a posto:

  • lo schema "Autenticazione di base" è preselezionato
  • la richiesta viene inviata con l' intestazione di autorizzazione
  • il Server risponde con un 200 OK
  • L'autenticazione riesce

4. Autenticazione di base con intestazioni HTTP non elaborate

Autenticazione di base preventiva significa fondamentalmente pre-inviare l' intestazione di autorizzazione .

Quindi, invece di passare attraverso l'esempio precedente piuttosto complesso per configurarlo, possiamo prendere il controllo di questa intestazione e costruirla a mano :

HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION); String auth = DEFAULT_USER + ":" + DEFAULT_PASS; byte[] encodedAuth = Base64.encodeBase64( auth.getBytes(StandardCharsets.ISO_8859_1)); String authHeader = "Basic " + new String(encodedAuth); request.setHeader(HttpHeaders.AUTHORIZATION, authHeader); HttpClient client = HttpClientBuilder.create().build(); HttpResponse response = client.execute(request); int statusCode = response.getStatusLine().getStatusCode(); assertThat(statusCode, equalTo(HttpStatus.SC_OK));

Assicuriamoci che funzioni correttamente:

[main] DEBUG ... - Auth cache not set in the context [main] DEBUG ... - Opening connection {}->//localhost:8080 [main] DEBUG ... - Connecting to localhost/127.0.0.1:8080 [main] DEBUG ... - Executing request GET /spring-security-rest-basic-auth/api/foos/1 HTTP/1.1 [main] DEBUG ... - Proxy auth state: UNCHALLENGED [main] DEBUG ... - http-outgoing-0 >> GET /spring-security-rest-basic-auth/api/foos/1 HTTP/1.1 [main] DEBUG ... - http-outgoing-0 >> Authorization: Basic dXNlcjE6dXNlcjFQYXNz [main] DEBUG ... - http-outgoing-0 << HTTP/1.1 200 OK

Quindi, anche se non è presente la cache di autenticazione, l' autenticazione di base funziona ancora correttamente e riceviamo 200 OK.

5. conclusione

Questo articolo ha illustrato vari modi per configurare e utilizzare l'autenticazione di base con Apache HttpClient 4.

Come sempre, il codice presentato in questo articolo è disponibile su Github. Questo è un progetto basato su Maven, quindi dovrebbe essere facile da importare ed eseguire così com'è.