Базовая и дайджест-аутентификация для службы REST с Spring Security

Базовая и дайджест-аутентификация для службы REST с Spring Security

1. обзор

В этой статье рассказывается, какset up both Basic and Digest Authentication on the same URI structure of a REST API. В предыдущей статье мы обсудили другой метод защиты службы REST -form-based authentication, поэтому обычная и дайджест-проверка подлинности является естественной альтернативой, а также более RESTful.

2. Конфигурация базовой аутентификации

Основная причина того, что аутентификация на основе форм не идеальна для службы RESTful, заключается в том, что Spring Security будетmake use of Sessions - это, конечно, состояние на сервере, поэтомуthe statelessness constraints in REST практически игнорируется.

Мы начнем с настройки базовой аутентификации - сначала мы удалим старую настраиваемую точку входа и фильтр из основного элемента безопасности<http>:


   

   

Обратите внимание, как поддержка базовой аутентификации была добавлена ​​с помощью одной строки конфигурации -<http-basic />, которая обрабатывает создание и подключение какBasicAuthenticationFilter, так иBasicAuthenticationEntryPoint.

2.1. Удовлетворение ограничения без гражданства - избавление от сессий

Одним из основных ограничений архитектурного стиля RESTful является то, что связь клиент-сервер полностьюstateless, посколькуoriginal dissertation читает:

5.1.3 Stateless

Затем мы добавляем ограничение к взаимодействию клиент-сервер: связь должна быть без состояния по своей природе, как в стиле клиент-без-состояния (CSS) в разделе 3.4.3 (рисунок 5-3), так что каждый запрос от клиента к Сервер должен содержать всю информацию, необходимую для понимания запроса, и не может использовать какой-либо сохраненный контекст на сервере. Session state is therefore kept entirely on the client.

КонцепцияSession на сервере имеет долгую историю в Spring Security, и полностью удалить ее до сих пор было трудно, особенно когда конфигурация выполнялась с использованием пространства имен.

Однако Spring Securityaugments конфигурация пространства имен сnew stateless option для создания сеанса, что эффективно гарантирует, что никакой сеанс не будет создан или использован Spring. Эта новая опция завершает удаление всех фильтров, относящихся к сеансу, из цепочки фильтров безопасности, обеспечивая проверку подлинности для каждого запроса.

3. Конфигурация дайджест-аутентификации

Начиная с предыдущей конфигурации, фильтр и точка входа, необходимые для настройки дайджест-аутентификации, будут определены как bean-компоненты. Затемdigest entry point заменит тот, который был создан<http-basic> за кулисами. Наконец, пользовательскийdigest filter будет введен в цепочку фильтров безопасности с использованием семантикиafter пространства имен безопасности для размещения его непосредственно после фильтра базовой аутентификации.


   

   
   



   
   



   
   



   
      
         
         
      
   

К сожалению, в пространстве имен безопасности нетsupport для автоматической настройки дайджест-аутентификации, как можно настроить базовую аутентификацию с помощью<http-basic>. Из-за этого необходимые компоненты должны были быть определены и подключены вручную в конфигурацию безопасности.

4. Поддержка обоих протоколов аутентификации в одной службе RESTful

Обычная или дайджест-проверка подлинности может быть легко реализована в Spring Security; он поддерживает оба из них для одной и той же веб-службы RESTful, в одних и тех же сопоставлениях URI, что вводит новый уровень сложности в настройку и тестирование службы.

4.1. Анонимный запрос

Как с базовым, так и с дайджест-фильтрами в цепочке безопасности, способanonymous request - запрос, не содержащий учетных данных аутентификации (HTTP-заголовокAuthorization) - обрабатывается Spring Security: два фильтра аутентификации найдутno credentials и продолжит выполнение цепочки фильтров. Затем, увидев, что запрос не был аутентифицирован, бросаетсяAccessDeniedException и перехватывается вExceptionTranslationFilter, который начинает точку входа дайджеста, запрашивая у клиента учетные данные.

Обязанности как основного, так и дайджест-фильтров очень узки - они будут продолжать выполнять цепочку фильтров безопасности, если не смогут определить тип учетных данных для аутентификации в запросе. Именно поэтому Spring Security может быть гибко настроен с поддержкой нескольких протоколов аутентификации на одном и том же URI.

Когда будет сделан запрос, содержащий правильные учетные данные аутентификации - базовый или дайджест - этот протокол будет использован правильно. Однако для анонимного запроса клиент получит запрос только для дайджест-аутентификации. Это связано с тем, что точка входа в дайджест настроена как основная и единственная точка входа в цепочку Spring Security; как таковойdigest authentication can be considered the default.

4.2. Запрос с учетными данными для аутентификации

request with credentials для обычной аутентификации будет идентифицироваться заголовкомAuthorization, начинающимся с префикса“Basic”. При обработке такого запроса учетные данные будут декодированы в базовом фильтре аутентификации, и запрос будет авторизован. Точно так же запрос с учетными данными для дайджест-аутентификации будет использовать префикс“Digest” для заголовкаAuthorization.

5. Тестирование обоих сценариев

Тесты будут использовать службу REST, создавая новый ресурс после аутентификации с помощью basic или digest:

@Test
public void givenAuthenticatedByBasicAuth_whenAResourceIsCreated_then201IsReceived(){
   // Given
   // When
   Response response = given()
    .auth().preemptive().basic( ADMIN_USERNAME, ADMIN_PASSWORD )
    .contentType( HttpConstants.MIME_JSON ).body( new Foo( randomAlphabetic( 6 ) ) )
    .post( paths.getFooURL() );

   // Then
   assertThat( response.getStatusCode(), is( 201 ) );
}
@Test
public void givenAuthenticatedByDigestAuth_whenAResourceIsCreated_then201IsReceived(){
   // Given
   // When
   Response response = given()
    .auth().digest( ADMIN_USERNAME, ADMIN_PASSWORD )
    .contentType( HttpConstants.MIME_JSON ).body( new Foo( randomAlphabetic( 6 ) ) )
    .post( paths.getFooURL() );

   // Then
   assertThat( response.getStatusCode(), is( 201 ) );
}

Обратите внимание, что тест с использованием базовой аутентификации добавляет учетные данные к запросуpreemptively, независимо от того, запрашивал ли сервер аутентификацию или нет. Это сделано для того, чтобы серверу не нужно было запрашивать у клиента учетные данные, потому что в противном случае проблема была бы в дайджесте учетных данных, поскольку это используется по умолчанию.

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

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