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

Spring Безопасность канала HTTP/HTTPS

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

1. Обзор

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

Использование HTTPS для аутентификации имеет решающее значение для защиты целостности конфиденциальных данных при транспортировке.

Статья основана на учебнике Spring Security Login , добавляя дополнительный уровень безопасности. Мы выделяем шаги, необходимые для защиты данных аутентификации, обслуживая страницу входа через закодированный канал HTTPS.

2. Первоначальная настройка без защиты канала

Начнем с конфигурации безопасности, описанной в вышеупомянутой статье.

Веб-приложение позволяет пользователям получать доступ:

  1. /anonymous.html без аутентификации,
  2. /login.html и
  3. другие страницы ( /homepage.html ) после успешного входа в систему.

Доступ контролируется следующей конфигурацией:

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/anonymous*")
.anonymous();

http.authorizeRequests()
.antMatchers("/login*")
.permitAll();

http.authorizeRequests()
.anyRequest()
.authenticated();

Или через XML:

<http use-expressions="true">
<intercept-url pattern="/anonymous*" access="isAnonymous()"/>
<intercept-url pattern="/login*" access="permitAll"/>
<intercept-url pattern="/**" access="isAuthenticated()"/>
</http>

На данный момент страница входа доступна по адресу:

http://localhost:8080/spring-security-login/login.html

Пользователи могут аутентифицировать себя через HTTP, однако это небезопасно, поскольку пароли будут отправлены в виде обычного текста.

3. Конфигурация HTTPS-сервера

Чтобы доставлять страницу входа только через HTTPS , ваш веб-сервер должен иметь возможность обслуживать страницы HTTPS . Для этого необходимо, чтобы поддержка SSL/TLS была включена.

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

Допустим, мы используем Tomcat и запускаем собственный сертификат. Сначала нам нужно создать хранилище ключей с самозаверяющим сертификатом.

Сгенерировать хранилище ключей можно с помощью следующей команды в терминале:

keytool -genkey -alias tomcat -keyalg RSA -storepass changeit -keypass changeit -dname 'CN=tomcat'

Это создаст закрытый ключ и самозаверяющий сертификат в хранилище ключей по умолчанию для вашего профиля пользователя в вашей домашней папке.

Следующий шаг — отредактировать conf/server.xml , чтобы он выглядел следующим образом:

<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="${user.home}/.keystore" keystorePass="changeit" />

Второй тег SSL/TLS <Connector> обычно закомментирован в файле конфигурации, поэтому достаточно раскомментировать и добавить информацию о хранилище ключей. Дополнительная информация доступна в соответствующей документации Tomcat .

С настроенной конфигурацией HTTPS страница входа в систему теперь также может обслуживаться по следующему URL-адресу:

https://localhost:8443/spring-security-login/login.html

Для веб-серверов, отличных от Tomcat, потребуется другая, но, вероятно, похожая конфигурация.

4. Настройка безопасности канала

На данный момент мы можем обслуживать страницу входа как по HTTP, так и по HTTPS. В этом разделе объясняется, как разрешить использование HTTPS.

Чтобы требовать HTTPS для страницы входа, измените конфигурацию безопасности, добавив следующее:

http.requiresChannel()
.antMatchers("/login*").requiresSecure();

Или добавьте атрибут require-channel="https" в конфигурацию XML:

<intercept-url pattern="/login*" access="permitAll" requires-channel="https"/>

После этого пользователи могли входить в систему только через HTTPS. Все относительные ссылки, например перенаправление на /homepage.html , унаследуют протокол исходного запроса и будут обслуживаться по протоколу HTTPS.

При смешивании HTTP- и HTTPS-запросов в одном веб-приложении необходимо учитывать дополнительные аспекты, требующие дополнительной настройки.

5. Смешивание HTTP и HTTPS

С точки зрения безопасности предоставление всего через HTTPS является хорошей практикой и твердой целью.

Однако, если использование исключительно HTTPS невозможно, мы можем настроить Spring для использования HTTP, добавив в конфигурацию следующее:

http.requiresChannel()
.anyRequest().requiresInsecure();

Или добавьте атрибуты require-channel="http" в XML:

<intercept‐url pattern="/**" access="isAuthenticated()" requires‐channel="http"/>

Это указывает Spring использовать HTTP для всех запросов, которые явно не настроены для использования HTTPS, но в то же время нарушает исходный механизм входа в систему. В следующих разделах объясняется основная причина.

5.1. Пользовательский URL-адрес обработки входа через HTTPS

Конфигурация безопасности в исходном учебнике по безопасности содержит следующее:

<form-login login-processing-url="/perform_login"/>

Без принуждения /perform_login к использованию HTTPS произойдет перенаправление на HTTP-вариант с потерей информации для входа, отправленной с исходным запросом.

Чтобы преодолеть это, нам нужно настроить Spring для использования HTTPS для URL-адреса обработки:

http.requiresChannel()
.antMatchers("/login*", "/perform_login");

Обратите внимание на дополнительный аргумент /perform_login , переданный методу antMatchers .

Эквивалент в конфигурации XML требует добавления в конфигурацию нового элемента < intercept-url> :

<intercept-url pattern="/perform_login" requires-channel="https"/>

Если ваше собственное приложение использует URL-адрес обработки входа по умолчанию (это /login ), вам не нужно настраивать это явно, так как шаблон /login* уже охватывает это.

С настроенной конфигурацией пользователи могут входить в систему, но не могут получать доступ к аутентифицированным страницам, например , /homepage.html по протоколу HTTP, из-за функции защиты фиксации сеанса Spring .

5.2. Отключение защиты от фиксации сеанса

Фиксация сеанса — проблема, которой нельзя избежать при переключении между HTTP и HTTPS.

По умолчанию Spring создает новый идентификатор сеанса после успешного входа в систему. Когда пользователь загружает страницу входа HTTPS, файл cookie идентификатора сеанса пользователя будет помечен как безопасный. После входа в систему контекст переключится на HTTP, и файл cookie будет потерян , поскольку HTTP небезопасен.

Чтобы этого избежать , не требуется устанавливать для защиты от фиксации сеанса значение none .

http.sessionManagement()
.sessionFixation()
.none();

Или через XML:

<session-management session-fixation-protection="none"/>

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

6. Тест

После применения всех этих изменений конфигурации доступ к /anonymous.html без входа в систему (используя либо http:// , либо https://) перенаправит вас на страницу через HTTP.

Открытие других страниц, таких как /homepage.html , должно привести к перенаправлению на страницу входа через HTTPS, а после входа вы будете перенаправлены обратно на /homepage.html с использованием HTTP.

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

В этом руководстве мы рассмотрели, как настроить веб-приложение Spring, которое взаимодействует через HTTP, за исключением механизма входа в систему. Однако новые современные веб-приложения почти всегда должны использовать исключительно HTTPS в качестве протокола связи. Снижение уровня безопасности или отключение функций безопасности (например, session-fixation-protection ) — не лучшая идея.

Это руководство основано на кодовой базе, доступной на GitHub . Конфигурацию безопасности канала можно включить, указав https в качестве активного профиля Spring .