Otentikasi Dasar HttpClient

1. Ikhtisar

Tutorial ini akan menggambarkan cara mengkonfigurasi Otentikasi Dasar di Apache HttpClient 4 .

Jika Anda ingin menggali lebih dalam dan mempelajari hal-hal keren lainnya yang dapat Anda lakukan dengan HttpClient - lanjutkan ke tutorial HttpClient utama .

2. Otentikasi Dasar Dengan API

Mari kita mulai dengan cara standar untuk mengonfigurasi Otentikasi Dasar di HttpClient - melalui 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));

Seperti yang bisa kita lihat, membuat klien dengan penyedia kredensial untuk menyiapkannya dengan Autentikasi Dasar tidaklah sulit.

Sekarang, untuk memahami apa yang sebenarnya akan dilakukan HttpClient di balik layar, kita perlu melihat 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

Seluruh komunikasi Client-Server sekarang jelas :

  • Klien mengirimkan Permintaan HTTP tanpa kredensial
  • Server mengirimkan kembali tantangan
  • Klien bernegosiasi dan mengidentifikasi skema otentikasi yang benar
  • Klien mengirimkan Permintaan kedua , kali ini dengan kredensial

3. Otentikasi Dasar Preemptive

Di luar kotak, HttpClient tidak melakukan otentikasi preemptive. Sebaliknya, ini harus menjadi keputusan eksplisit yang dibuat oleh klien.

Pertama, kita perlu membuat HttpContext - mengisinya dengan cache otentikasi dengan jenis skema otentikasi yang benar telah dipilih sebelumnya. Ini berarti bahwa negosiasi dari contoh sebelumnya tidak lagi diperlukan - Otentikasi Dasar sudah dipilih :

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

Sekarang kita dapat menggunakan klien dengan konteks baru dan mengirim permintaan pra-otentikasi :

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

Mari kita lihat lognya:

[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

Semuanya terlihat baik-baik saja:

  • skema "Otentikasi Dasar" telah dipilih sebelumnya
  • Permintaan dikirim dengan header Otorisasi
  • Server merespons dengan 200 OK
  • Otentikasi berhasil

4. Autentikasi Dasar Dengan Header HTTP Mentah

Autentikasi Dasar Preemptive pada dasarnya berarti pra-pengiriman header Otorisasi .

Jadi, alih-alih melalui contoh sebelumnya yang agak rumit untuk menyiapkannya, kita dapat mengontrol tajuk ini dan membuatnya dengan tangan :

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

Mari kita pastikan ini bekerja dengan benar:

[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

Jadi, meskipun tidak ada cache autentikasi , Autentikasi Dasar masih berfungsi dengan benar dan kami menerima 200 OK.

5. Kesimpulan

Artikel ini mengilustrasikan berbagai cara untuk menyiapkan dan menggunakan otentikasi dasar dengan Apache HttpClient 4.

Seperti biasa, kode yang disajikan dalam artikel ini tersedia di Github. Ini adalah proyek berbasis Maven, jadi semestinya mudah untuk mengimpor dan menjalankan apa adanya.