HttpClient Basic Authentication

1. Общ преглед

Този урок ще илюстрира как да конфигурирате основно удостоверяване на Apache HttpClient 4 .

Ако искате да копаете по-дълбоко и да научите други страхотни неща, които можете да направите с HttpClient - преминете към основния урок за HttpClient .

2. Основно удостоверяване с API

Нека започнем със стандартния начин за конфигуриране на основно удостоверяване на HttpClient - чрез 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));

Както виждаме, създаването на клиента с доставчик на идентификационни данни, който да го настрои с Basic Authentication, не е трудно.

Сега, за да разберем какво всъщност ще направи HttpClient зад кулисите, ще трябва да разгледаме дневниците:

# ... 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

Цялата комуникация клиент-сървър вече е ясна :

  • клиентът изпраща HTTP заявката без идентификационни данни
  • сървърът изпраща обратно предизвикателство
  • Клиентът договаря и идентифицира правилната схема за удостоверяване
  • клиентът изпраща втора заявка , този път с идентификационни данни

3. Превантивно основно удостоверяване

Извън кутията HttpClient не прави превантивно удостоверяване. Вместо това това трябва да бъде изрично решение, взето от клиента.

Първо, трябва да създадем HttpContext - предварително да го попълним с кеш за удостоверяване с предварително избран правилен тип схема за удостоверяване. Това ще означава, че преговорите от предишния пример вече не са необходими - основно удостоверяване вече е избрано :

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

Сега можем да използваме клиента с новия контекст и да изпратим заявката за предварително удостоверяване :

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

Нека да разгледаме дневниците:

[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

Всичко изглежда ОК:

  • схемата „Основно удостоверяване“ е предварително избрана
  • заявката се изпраща със заглавката за разрешение
  • сървърът отговаря с 200 OK
  • Удостоверяването е успешно

4. Основна Auth с Raw HTTP заглавки

Preemptive Basic Authentication основно означава предварително изпращане на заглавката Authorization .

Така че, вместо да преминем през доста сложния предишен пример, за да го настроим, можем да поемем контрола над този хедър и да го изградим на ръка :

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

Нека се уверим, че това работи правилно:

[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

Така че, въпреки че няма кеш за удостоверяване, Basic Authentication все още работи правилно и получаваме 200 OK.

5. Заключение

Тази статия илюстрира различни начини за настройване и използване на основно удостоверяване с Apache HttpClient 4.

Както винаги, кодът, представен в тази статия, е достъпен в Github. Това е проект, базиран на Maven, така че трябва да е лесно да се импортира и да се изпълнява както е.