Authentification de base HttpClient

Authentification de base HttpClient

1. Vue d'ensemble

Ce didacticiel illustrera commentconfigure Basic Authentication on the Apache HttpClient 4.

Si vous voulez approfondir et apprendre d'autres choses intéressantes que vous pouvez faire avec HttpClient, rendez-vous surthe main HttpClient tutorial.

Lectures complémentaires:

Tutoriel HttpAsyncClient

Tutoriel HttpAsyncClient - envoyez une requête GET de base, utilisez le client multithread, configurez le client avec SSL ainsi qu'avec un proxy et, enfin, effectuez l'authentification.

Read more

Configuration avancée du client

Configurations HttpClient pour les cas d'utilisation avancés.

Read more

2. Authentification de base avec l'API

Commençons parthe standard way of configuring Basic Authentication on the HttpClient – via a 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));

Comme nous pouvons le constater, la création du client avec un fournisseur d'informations d'identification pour le configurer avec l'authentification de base n'est pas difficile.

Maintenant, pour comprendre ce queHttpClient va réellement faire dans les coulisses, nous devons examiner les journaux:

# ... 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'ensemble desClient-Server communication is now clear:

  • le client envoie la requête HTTP sans informations d'identification

  • le serveur renvoie un défi

  • le client négocie et identifie le bon schéma d'authentification

  • le client envoiea second Request, cette fois avec les informations d'identification

3. Authentification de base préemptive

Hors de la boîte, leHttpClient ne fait pas d'authentification préemptive. Au lieu de cela, cela doit être une décision explicite prise par le client.

Tout d'abord,we need to create the HttpContext – pre-populating it with an authentication cache avec le bon type de schéma d'authentification présélectionné. Cela signifie que la négociation de l'exemple précédent n'est plus nécessaire -Basic Authentication is already chosen:

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);

Nous pouvons maintenant utiliser le client avec le nouveau contexte etsend the pre-authentication request:

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));

Examinons les journaux:

[main] DEBUG ... - Re-using cached 'basic' auth scheme for http://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

Tout va bien:

  • le schéma «Authentification de base» est pré-sélectionné

  • la demande est envoyée avec l'en-têteAuthorization

  • le serveur répond par un200 OK

  • L'authentification réussit

4. Authentification de base avec en-têtes HTTP bruts

L'authentification de base préemptive signifie essentiellement l'envoi préalable de l'en-têteAuthorization.

Donc, au lieu de passer par l'exemple précédent plutôt complexe pour le configurer,we can take control of this header and construct it by hand:

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));

Vérifions que cela fonctionne correctement:

[main] DEBUG ... - Auth cache not set in the context
[main] DEBUG ... - Opening connection {}->http://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

Donc, même s'il n'y a pas de cache d'authentification,Basic Authentication still works correctly and we receive 200 OK.

5. Conclusion

Cet article illustre différentes manières de configurer et d'utiliser l'authentification de base avec Apache HttpClient 4.

Comme toujours, le code présenté dans cet article est disponibleover on Github. Ceci est un projet basé sur Maven, il devrait donc être facile à importer et à exécuter tel quel.