Базовая аутентификация с помощью RestTemplate
Оглавление
1. обзор
В этой статье показано, как использовать пружины отRestTemplate доconsume a RESTful Service secured with Basic Authentication.
После настройки базовой аутентификации для шаблона каждый запрос будет отправленpreemptively containing the full credentials, необходимый для выполнения процесса аутентификации. Учетные данные будут закодированы и будут использовать HTTP-заголовокAuthorization в соответствии со спецификациями схемы базовой аутентификации. Пример будет выглядеть так:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Дальнейшее чтение:
Spring RestTemplate Обработка ошибок
Узнайте, как обрабатывать ошибки с помощью Spring RestTemplate
Использование перехватчика Spring RestTemplate
Узнайте об использовании перехватчиков в приложении Spring с RestTemplate.
Изучение Spring Boot TestRestTemplate
Узнайте, как использовать новый TestRestTemplate в Spring Boot для тестирования простого API.
2. НастройкаRestTemplate
ЗагрузкуRestTemplate в контекст Spring можно выполнить, просто объявив для него bean-компонент; однако установкаRestTemplate с помощьюBasic Authentication потребует ручного вмешательства, поэтому вместо непосредственного объявления bean-компонента для большей гибкости будет использоваться SpringFactoryBean. Эта фабрика создаст и настроит шаблон при инициализации:
@Component
public class RestTemplateFactory
implements FactoryBean, InitializingBean {
private RestTemplate restTemplate;
public RestTemplate getObject() {
return restTemplate;
}
public Class 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));
}
}
Значенияhost иport должны зависеть от среды, что позволяет клиенту гибко определять один набор значений для интеграционного тестирования, а другой - для производственного использования. Значениями можно управлять с помощьюfirst class Spring support for properties files.
3. Ручное управление HTTP-заголовком авторизации
Процесс создания заголовкаAuthorization относительно прост для базовой аутентификации, поэтому его можно в значительной степени сделать вручную с помощью нескольких строк кода:
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(createHeaders(username, password)), clazz);
4. Автоматическое управление HTTP-заголовком авторизации
Spring 3.0 и 3.1, а теперь и 4.x очень хорошо поддерживают HTTP-библиотеки Apache:
-
Spring 3.0,CommonsClientHttpRequestFactory интегрирован с nowend-of-life’dHttpClient 3.x
-
Spring 3.1 представила поддержку текущегоHttpClient 4.x черезHttpComponentsClientHttpRequestFactory (поддержка добавлена в JIRASPR-6180)
-
Spring 4.0 представила поддержку асинхронного режима черезHttpComponentsAsyncClientHttpRequestFactory
Давайте начнем настраивать с HttpClient 4 и Spring 4.
RestTemplate потребует фабрику HTTP-запросов - фабрику, поддерживающую базовую аутентификацию - пока все хорошо. Однако прямое использование существующегоHttpComponentsClientHttpRequestFactory окажется затруднительным, поскольку архитектураRestTemplate была разработанаwithout good support для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 - этоa bit of a burden: информация для аутентификации кэшируется, и процесс настройки этого кеша аутентификации очень ручной и неинтуитивно.
Теперь все готово -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, см.check out this article.
5. Maven Зависимости
Следующие зависимости Maven требуются для самогоRestTemplate и для библиотеки HttpClient:
org.springframework
spring-webmvc
5.0.6.RELEASE
org.apache.httpcomponents
httpclient
4.5.3
Необязательно, если заголовок HTTPAuthorization создается вручную, тогда для поддержки кодирования требуется дополнительная библиотека:
commons-codec
commons-codec
1.10
Вы найдете самые новые версии вMaven repository.
6. Заключение
Хотя ветвь разработки 3.x для Apache HttpClient уже давно подошла к концу, а поддержка Spring для этой версии полностью устарела, большая часть информации, которую можно найти вRestTemplate и безопасности по-прежнему не учитывает выпусковthe current HttpClient 4.x. Эта статья представляет собой попытку изменить это с помощью подробного пошагового обсуждения того, как настроить базовую аутентификацию с помощьюRestTemplate и как использовать ее для использования защищенного REST API.
Чтобы выйти за рамки примеров кода в статье с реализацией как потребляющей стороны, рассмотренной здесь, так и фактической службы RESTful, взгляните на проектover on Github.
Это проект, основанный на Maven, поэтому его легко импортировать и запускать как есть.