1. Обзор
В этом руководстве показано, как использовать HTTPS для защиты страницы входа в приложение с помощью функции безопасности канала Spring.
Использование HTTPS для аутентификации имеет решающее значение для защиты целостности конфиденциальных данных при транспортировке.
Статья основана на учебнике Spring Security Login , добавляя дополнительный уровень безопасности. Мы выделяем шаги, необходимые для защиты данных аутентификации, обслуживая страницу входа через закодированный канал HTTPS.
2. Первоначальная настройка без защиты канала
Начнем с конфигурации безопасности, описанной в вышеупомянутой статье.
Веб-приложение позволяет пользователям получать доступ:
/anonymous.html
без аутентификации,/login.html
и- другие страницы (
/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 .