Перейти к основному содержимому

RestTemplate с дайджест-аутентификацией

· 3 мин. чтения

1. Обзор

В этой статье будет показано, как настроить Spring RestTemplate для использования службы, защищенной с помощью дайджест-аутентификации .

Как и в случае с базовой аутентификацией, после того, как в шаблоне будет установлена дайджест-аутентификация, клиент сможет выполнить необходимые шаги безопасности и получить информацию, необходимую для заголовка авторизации :

Authorization: Digest 
username="user1",
realm="Custom Realm Name",
nonce="MTM3NTYwOTA5NjU3OTo5YmIyMjgwNTFlMjdhMTA1MWM3OTMyMWYyNDY2MGFlZA==",
uri="/spring-security-rest-digest-auth/api/foos/1",
....

С помощью этих данных сервер может правильно аутентифицировать запрос и вернуть ответ 200 OK.

2. Настройте RestTemplate

RestTemplate должен быть объявлен как bean-компонент в контексте Spring — это достаточно просто либо в XML, либо в простой Java, используя аннотацию @Bean :

import org.apache.http.HttpHost;
import com.foreach.client.HttpComponentsClientHttpRequestFactoryDigestAuth;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ClientConfig {

@Bean
public RestTemplate restTemplate() {
HttpHost host = new HttpHost("localhost", 8080, "http");
CloseableHttpClient client = HttpClientBuilder.create().
setDefaultCredentialsProvider(provider()).useSystemProperties().build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactoryDigestAuth(host, client);

return new RestTemplate(requestFactory);;
}

private CredentialsProvider provider() {
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials =
new UsernamePasswordCredentials("user1", "user1Pass");
provider.setCredentials(AuthScope.ANY, credentials);
return provider;
}
}

Большая часть настройки механизма доступа к дайджесту выполняется в пользовательской реализации фабрики клиентских http-запросов, внедренной в шаблон — HttpComponentsClientHttpRequestFactoryDigestAuth .

Обратите внимание, что сейчас мы предварительно настраиваем шаблон с учетными данными, которые имеют доступ к защищенному API.

3. Настройте дайджест-аутентификацию

Мы собираемся использовать поддержку, представленную в Spring 3.1 для текущего HttpClient 4.x, а именно HttpComponentsClientHttpRequestFactory , путем его расширения и настройки.

В основном мы собираемся настроить HttpContext и подключить нашу пользовательскую логику для дайджест-аутентификации:

import java.net.URI;
import org.apache.http.HttpHost;
import org.apache.http.client.AuthCache;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.auth.DigestScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;

public class HttpComponentsClientHttpRequestFactoryDigestAuth
extends HttpComponentsClientHttpRequestFactory {

HttpHost host;

public HttpComponentsClientHttpRequestFactoryDigestAuth(HttpHost host, HttpClient httpClient) {
super(httpClient);
this.host = host;
}

@Override
protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
return createHttpContext();
}

private HttpContext createHttpContext() {
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate DIGEST scheme object, initialize it and add it to the local auth cache
DigestScheme digestAuth = new DigestScheme();
// If we already know the realm name
digestAuth.overrideParamter("realm", "Custom Realm Name");
authCache.put(host, digestAuth);

// Add AuthCache to the execution context
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
return localcontext;
}
}

Теперь RestTemplate можно просто внедрить и использовать в тесте:

@Test
public void whenSecuredRestApiIsConsumed_then200OK() {
String uri = "http://localhost:8080/spring-security-rest-digest-auth/api/foos/1";
ResponseEntity<Foo> entity = restTemplate.exchange(uri, HttpMethod.GET, null, Foo.class);
System.out.println(entity.getStatusCode());
}

Чтобы проиллюстрировать полный процесс настройки, в этом тесте также настраиваются учетные данные пользователя — user1 и user1Pass . Эту часть следует, конечно, сделать только один раз и вне самого теста .

4. Зависимости Maven

Требуемые зависимости Maven для RestTemplate и библиотеки HttpClient:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>

5. Вывод

В этом руководстве показано, как установить и настроить Rest Template, чтобы он мог использовать приложение, защищенное дайджест-аутентификацией . Сам REST API необходимо настроить с помощью механизма безопасности дайджеста .

Реализацию можно найти в примере проекта GitHub — это проект на основе Maven, поэтому его легко импортировать и запускать как есть.