Оглавление
- 1. Обзор
- 2. Настройка
RestTemplate
в Spring - 3. Ручное управление HTTP-заголовком авторизации
- 4. Автоматическое управление HTTP-заголовком авторизации
- 5. Зависимости Maven
- 6. Заключение
1. Обзор
В этом руководстве мы узнаем, как использовать Spring RestTemplate
для использования службы RESTful, защищенной с помощью базовой аутентификации .
После того, как мы настроим обычную аутентификацию для шаблона, каждый запрос будет отправляться заранее, содержащий полные учетные данные , необходимые для выполнения процесса аутентификации. Учетные данные будут закодированы и будут использовать HTTP- заголовок авторизации
в соответствии со спецификациями схемы базовой аутентификации. Пример будет выглядеть так:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
2. Настройка RestTemplate
Мы можем загрузить RestTemplate
в контекст Spring, просто объявив для него bean-компонент; однако настройка RestTemplate
с базовой аутентификацией потребует ручного вмешательства, поэтому вместо прямого объявления компонента мы будем использовать Spring FactoryBean
для большей гибкости. Этот FactoryBean
создаст и настроит шаблон при инициализации:
@Component
public class RestTemplateFactory
implements FactoryBean<RestTemplate>, InitializingBean {
private RestTemplate restTemplate;
public RestTemplate getObject() {
return restTemplate;
}
public Class<RestTemplate> getObjectType() {
return RestTemplate.class;
}
public boolean isSingleton() {
return true;
}
public void afterPropertiesSet() {
HttpHost host = new HttpHost("localhost", 8082, "http");
restTemplate = new RestTemplate(
new HttpComponentsClientHttpRequestFactoryBasicAuth(host));
}
}
Значения хоста
и порта
должны зависеть от среды, что позволяет клиенту гибко определять один набор значений для интеграционного тестирования, а другой — для производственного использования. Значения могут управляться первоклассной поддержкой Spring для файлов свойств .
3. Ручное управление HTTP-заголовком авторизации
Для нас довольно просто создать заголовок авторизации
для базовой аутентификации, поэтому мы можем сделать это вручную с помощью нескольких строк кода:
HttpHeaders createHeaders(String username, String password){
return new HttpHeaders() {{
String auth = username + ":" + password;
byte[] encodedAuth = Base64.encodeBase64(
auth.getBytes(Charset.forName("US-ASCII")) );
String authHeader = "Basic " + new String( encodedAuth );
set( "Authorization", authHeader );
}};
}
Кроме того, отправить запрос так же просто:
restTemplate.exchange
(uri, HttpMethod.POST, new HttpEntity<T>(createHeaders(username, password)), clazz);
4. Автоматическое управление HTTP-заголовком авторизации
Spring 3.0 и 3.1, а теперь и 4.x имеют очень хорошую поддержку HTTP-библиотек Apache:
- В Spring 3.0
CommonsClientHttpRequestFactory
интегрировался сHttpClient 3.x
, срок службы которого уже истек. `` - В Spring 3.1 появилась поддержка текущего HttpClient 4.x через
HttpComponentsClientHttpRequestFactory
(поддержка добавлена в JIRA SPR-6180 ). - В Spring 4.0 появилась асинхронная поддержка через
HttpComponentsAsyncClientHttpRequestFactory.
Давайте начнем настройку с HttpClient 4 и Spring 4.
Для RestTemplate
потребуется фабрика HTTP-запросов, поддерживающая обычную аутентификацию. Однако прямое использование существующей HttpComponentsClientHttpRequestFactory
окажется затруднительным, поскольку архитектура RestTemplate
была разработана без хорошей поддержки HttpContext , важной
части головоломки. Таким образом, нам нужно создать подкласс HttpComponentsClientHttpRequestFactory
и переопределить метод createHttpContext
:
public class HttpComponentsClientHttpRequestFactoryBasicAuth
extends HttpComponentsClientHttpRequestFactory {
HttpHost host;
public HttpComponentsClientHttpRequestFactoryBasicAuth(HttpHost host) {
super();
this.host = host;
}
protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
return createHttpContext();
}
private HttpContext createHttpContext() {
AuthCache authCache = new BasicAuthCache();
BasicScheme basicAuth = new BasicScheme();
authCache.put(host, basicAuth);
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(HttpClientContext.AUTH_CACHE, authCache);
return localcontext;
}
}
Мы встроили базовую поддержку аутентификации здесь, при создании HttpContext
. Как мы видим, выполнение упреждающей базовой аутентификации с помощью HttpClient 4.x для нас немного обременительно. Информация об аутентификации кэшируется, и нам очень сложно настроить этот кэш аутентификации вручную и неинтуитивно.
Теперь, когда все готово, RestTemplate
сможет поддерживать схему базовой аутентификации, просто добавив BasicAuthorizationInterceptor:
restTemplate.getInterceptors().add(
new BasicAuthorizationInterceptor("username", "password"));
Затем запрос:
restTemplate.exchange(
"http://localhost:8082/spring-security-rest-basic-auth/api/foos/1",
HttpMethod.GET, null, Foo.class);
Для подробного обсуждения того, как защитить саму службу REST, ознакомьтесь с этой статьей .
5. Зависимости Maven
Нам потребуются следующие зависимости Maven для самого RestTemplate
и для библиотеки HttpClient:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
При желании, если мы создадим заголовок авторизации
HTTP вручную, нам потребуется дополнительная библиотека для поддержки кодирования:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
Самые свежие версии мы можем найти в репозитории Maven .
6. Заключение
Большая часть информации, которую можно найти в RestTemplate
и безопасности, по-прежнему не учитывает текущие выпуски HttpClient 4.x, даже несмотря на то, что ветка 3.x устарела, а поддержка этой версии Spring полностью устарела. . В этой статье мы попытаемся изменить это, пройдя подробное пошаговое обсуждение того, как настроить обычную аутентификацию с помощью RestTemplate
и использовать его для использования защищенного REST API.
Чтобы выйти за рамки примеров кода в этой статье с реализацией потребляющей стороны и реальной службы RESTful, взгляните на проект на Github.
Это проект на основе Maven, поэтому его легко импортировать и запускать как есть.