Spring Security: руководство по настройке и кастомизации
TL;DR
Spring Security обеспечивает аутентификацию и авторизацию для приложений Spring Boot. В статье показано, как добавить зависимость, настроить регистрацию и вход, создать UserDetailsService и SecurityFilterChain, а также как задать права доступа для отдельных URL. Включены чек-листы, рекомендации по безопасности и тесты приёмки.

Spring Security защищает приложение через аутентификацию и авторизацию. По умолчанию Spring Security требует аутентификации для каждого HTTP-запроса (каждой страницы) приложения для единого глобального пользователя.
Фреймворк очень гибкий: вы можете задать индивидуальные правила безопасности для каждого HTTP-пути и для разных типов пользователей. Это позволяет убрать ограничения на публичные страницы (например, главную), и назначать роли/права конкретным типам пользователей.
Основная цель статьи и варианты запросов
primary intent: как настроить Spring Security в Spring Boot related variants: [“настройка Spring Security”, “Spring Security tutorial”, “Spring Boot security configuration”, “регистрация и вход Spring”, “SecurityFilterChain пример“, “UserDetailsService в Spring”]
Добавление Spring Security в приложение
Есть два пути добавить Spring Security: выбрать зависимость при создании проекта через Spring Initializr или добавить зависимость в файл сборки после генерации проекта.
- Для Gradle: файл зависимостей — build.gradle.
- Для Maven: файл — pom.xml.
Пример зависимости для Gradle (вставьте в секцию dependencies в build.gradle):
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
}Пример зависимости для Maven (вставьте в pom.xml):
org.springframework.boot
spring-boot-starter-security
Пример полноценного приложения (используемое в статье) доступен в репозитории GitHub и распространяется под лицензией MIT.
Быстрый запуск и поведение по умолчанию
После добавления зависимости запустите приложение и откройте любую страницу (например, корень). Простой контроллер для начальной проверки может выглядеть так:
package com.springSecurityDemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WebController {
@GetMapping("/")
public String home() {
return "Welcome!";
}
}После запуска вы увидите экран логина Spring Boot:
По умолчанию приложение перенаправляет на /login и требует пользователь/пароль. Логин по умолчанию — user, а пароль автоматически сгенерирован и выводится в консоли в виде строки:
Using generated security password: c4070465-4c65-4e72-8c3f-3800e631ba81Пароль меняется при каждом перезапуске приложения; логин остаётся тем же.
Кастомизация Spring Security — обзор
Чтобы изменить поведение безопасности, нужно переопределить конфигурацию Spring Security. Для примера и удобства мы добавим следующие зависимости в проект (помимо spring-boot-starter-security):
- Spring Data JPA
- MySQL JDBC Driver (или другой драйвер для выбранной БД)
- Thymeleaf (для рендеринга view)
- Lombok (по желанию, для сокращения шаблонного кода)
Thymeleaf формирует HTML-страницы, JPA и драйвер — работу с базой, Lombok уменьшает количество шаблонного кода.
Конфигурация доступа к базе данных
В application.properties (resources) укажите параметры подключения к БД. Пример для MySQL:
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/spring_security
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=updateОбновите значения URL, имя пользователя и пароль в соответствии с вашей средой.
Структура представлений и требуемые страницы
В примере используется 6 представлений (views):
- Главная страница (Home Page)
- Страница регистрации (Registration Page)
- Страница входа (Login Page)
- Страница логаута (Logout Page)
- Страница пользователя (User Page) — защищённая
- Страница ошибки (Error Page)
Только User Page требует авторизации: пользователь должен зарегистрироваться и войти в систему, чтобы получить доступ.
Контроллер регистрации
Пакет controller содержит классы, обрабатывающие HTTP-запросы. Ниже — пример RegistrationController для пути /register:
@Controller
@RequestMapping("/register")
public class RegistrationController {
private UserRepository userRepo;
private PasswordEncoder passwordEncoder;
public RegistrationController(UserRepository userRepo, PasswordEncoder passwordEncoder) {
this.userRepo = userRepo;
this.passwordEncoder = passwordEncoder;
}
@GetMapping
public String registerForm() {
return "registration";
}
@PostMapping
public String processRegistration(RegistrationForm form) {
userRepo.save(form.toUser(passwordEncoder));
return "redirect:/login";
}
}- @RequestMapping(“/register”) — все запросы к /register обрабатывает этот контроллер.
- @GetMapping возвращает форму регистрации.
- @PostMapping принимает данные из RegistrationForm, шифрует пароль через PasswordEncoder и сохраняет пользователя в БД.
Важно: представления (registration.html и т. п.) должны корректно отправлять поля на /register методом POST.
Создание конфигурации безопасности на Java
Начиная с Spring Security 5 и Spring 3.1, конфигурации удобно писать на Java-annotated классах вместо XML. Класс конфигурации отмечается @Configuration.
@Configuration
public class SecurityConfiguration {
}В этот класс мы добавим необходимые бины: PasswordEncoder, UserDetailsService и SecurityFilterChain.
Bean: PasswordEncoder
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}PasswordEncoder используется для хеширования паролей перед сохранением и для проверки при логине.
Bean: UserDetailsService
@Bean
public UserDetailsService userDetailsService(UserRepository userRepo) {
return username -> {
Customer customer = userRepo.findByUsername(username);
if (customer != null)
return customer;
throw new UsernameNotFoundException("Customer '" + username + "' not found");
};
}UserDetailsService извлекает пользователя из репозитория по username и возвращает объект, совместимый с UserDetails. В примере Customer реализует интерфейс UserDetails и содержит логику getAuthorities().
Bean: SecurityFilterChain
Filter chain определяет, какие URL защищены и какие — публичны. Пример:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/user").hasAuthority("USER").anyRequest().permitAll())
.formLogin(formLogin -> formLogin
.loginPage("/login").defaultSuccessUrl("/user", true))
.logout(logout -> logout.logoutSuccessUrl("/logout"));
return http.build();
}Разбор конфигурации:
- requestMatchers(“/user”).hasAuthority(“USER”) — только пользователи с 권алостью USER могут заходить на /user.
- anyRequest().permitAll() — все остальные URL открыты.
- formLogin(…) — пользователь будет перенаправлен на /login и после успешного входа — на /user.
- logout(…) — редирект после логаута на /logout.
Функция getAuthorities в классе Customer может выглядеть так:
@Override
public Collection extends GrantedAuthority> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("USER"));
}Это придаёт роли USER каждому новому зарегистрированному клиенту.
Когда стандартная настройка не подходит — варианты расширения
Ниже перечислены распространённые сценарии и альтернативы:
- Несколько ролей и уровней доступа: используйте hasRole(“ADMIN”) или access expressions для более гибкой логики.
- Статические ресурсы (CSS/JS/images): не забудьте разрешить доступ к ним через .requestMatchers(“/css/“, “/js/“).permitAll().
- Раздельные настройки для API и страниц: можно настроить отдельные SecurityFilterChain для REST API (JWT) и для web-форм (сессии).
- Аутентификация через OAuth2 / OpenID Connect: подключите spring-boot-starter-oauth2-client.
- Поддержка нескольких UserDetailsService (например, внутренние пользователи + LDAP): реализуйте CompositeUserDetailsService или настроьте AuthenticationProvider-ы.
Практические рекомендации и контрольные списки
Минимальный чек-лист перед выпуском в прод
- Пароли хранятся хешированными (BCrypt/Argon2).
- Удалён генератор пароля по умолчанию в логах (убрать вывод в консоль).
- Защищены все приватные URL.
- Разрешён доступ к статике.
- Включён CSRF для форм (если используется сессия).
- Для API с токенами CSRF отключён, вместо этого использованы заголовки/токены.
- Логины и сессии защищены HTTPS/TLS в проде.
Роли и права — шаблон таблицы
| Роль | Доступные страницы | Комментарий |
|---|---|---|
| ANON | /, /login, /register, /css/ | Публичный доступ |
| USER | /user, /profile | Доступ после регистрации |
| ADMIN | /admin/ | Только администраторам |
Роль-зависимые задачи для разработчика
- Для frontend: показывать/скрывать элементы UI в зависимости от роли.
- Для backend: дополнительно проверять права на уровне сервиса/методов (@PreAuthorize).
Тесты и критерии приёмки
Короткий набор тест-кейсов для проверки безопасности:
- Регистрация: при POST /register с валидными данными пользователь создаётся и получает роль USER.
- Логин: с корректными данными пользователь перенаправляется на /user.
- Доступ к /user без аутентификации -> 302 редирект на /login.
- Доступ к статике без аутентификации -> 200.
- Логаут: после /logout сессия уничтожается и доступ к /user запрещён.
Критерии приёмки:
- Все тесты выше проходят в среде staging.
- Нет утечек паролей в логах.
Планы миграции и совместимость
Если вы подключаете Spring Security в уже работающий проект:
- Подготовьте staging-окружение.
- Добавьте зависимости и временно разрешите все URL (security в permissive режиме).
- Постепенно включайте ограничение доступа для критических путей и проверяйте функциональность.
- Обновите UI: формы логина/регистрации, обработку ошибок.
- После валидации — включите строгие правила и переведите в prod.
Совместимость:
- Конфигурация на Java подходит для современных версий Spring Boot. Для старых версий может потребоваться WebSecurityConfigurerAdapter (устарел в новых релизах).
Укрепление безопасности (security hardening)
Рекомендации по повышению безопасности без конкретных чисел:
- Используйте BCrypt или Argon2 вместо простых хешей.
- Ограничьте число неудачных попыток входа (rate limiting, lockout).
- Включите HTTPS и HSTS в продовой среде.
- Обновляйте зависимости безопасности (регулярные обновления Spring и библиотек).
- Разделяйте права: принцип наименьших привилегий.
- Логируйте события безопасности (успех/неудача логина, изменение пароля) и храните логи в защищённом месте.
- Для REST API используйте OAuth2/JWT вместо сессий, при необходимости.
Важно: не храните чувствительные данные в логах и не передавайте пароли по незащищённым каналам.
Privacy и соответствие GDPR (если есть пользователи из ЕС)
Если приложение обрабатывает персональные данные:
- Храните минимально необходимую информацию о пользователе.
- Позвольте пользователю запросить удаление данных (право быть забытым).
- Шифруйте персональные данные в хранении, если необходимо.
- Документируйте цели обработки и основы правовой обработки данных.
Эти рекомендации являются общими; для соответствия закону проконсультируйтесь с юрисконсультом.
Отказоустойчивость: сценарий отката и быстрый план действий
Если новая конфигурация вызывает проблемы в проде:
- Откатите конфигурацию безопасности до последней рабочей версии (контролируемый релиз).
- Временно откройте доступ к критическим страницам (в безопасном режиме) для восстановления работы.
- Соберите логи и воспроизведите проблему в staging.
- Исправьте причину и разверните исправление через CI/CD.
Примеры альтернативных подходов
- JWT для SPA/API: хранение токенов на клиенте, stateless-аутентификация.
- LDAP/Active Directory для корпоративной авторизации.
- Использование внешнего провайдера OAuth2 (Google, GitHub) для аутентификации.
Выбор зависит от требований: масштаб, необходимость единого входа (SSO), тип клиента (серверные шаблоны vs SPA).
Факты и контрольные числа (факт-бокс)
- Spring Security — стандартное решение для Java-приложений на Spring.
- BCrypt — надёжный адаптивный хеш-функция для паролей.
- Принцип наименьших привилегий уменьшает риск утечек через скомпрометированные аккаунты.
(Числа приведены как контекстуальные указания; для конкретных метрик используйте данные вашего окружения.)
Шаблоны и чек-листы
Ниже — минимальная структура проекта (папки):
- /src/main/java/com/yourapp/controller — контроллеры
- /src/main/java/com/yourapp/model — сущности (Customer/User)
- /src/main/java/com/yourapp/repository — интерфейсы JPA
- /src/main/java/com/yourapp/security — SecurityConfiguration, бины
- /src/main/resources/templates — Thymeleaf-шаблоны
- /src/main/resources/application.properties — конфигурация БД и др.
Пример теста интеграции (псевдокод):
- Запустить приложение в тестовом профиле со встроенной БД.
- Выполнить POST /register.
- Выполнить POST /login с учётными данными.
- Проверить доступ к /user.
Decision tree для выбора модели аутентификации
flowchart TD
A[Какой клиент?] -->|Серверные HTML-страницы| B[Session-based 'formLogin']
A -->|SPA или мобильное приложение| C[Token-based 'JWT / OAuth2']
B --> D{Нужен SSO?}
D -->|Да| E[OAuth2/OpenID Connect]
D -->|Нет| F[Стандартный LDAP/DB users]
C --> G{Требуется хранение сессий на сервере?}
G -->|Да| F
G -->|Нет| H[JWT stateless]1-строчная глоссарий
- Аутентификация: проверка личности пользователя.
- Авторизация: проверка прав доступа к ресурсу.
- UserDetailsService: интерфейс для загрузки пользователя по username.
- SecurityFilterChain: последовательность фильтров безопасности для HTTP-запросов.
- PasswordEncoder: компонент для хеширования паролей.
Короткое резюме
- Spring Security по умолчанию защищает все пути и предоставляет логин/пароль.
- Для кастомизации добавьте PasswordEncoder, UserDetailsService и SecurityFilterChain.
- Назначайте роли и права через authorities/roles и защищайте URL через requestMatchers.
- Проверяйте безопасность через тесты и следуйте практикам hardening перед релизом.
Important: в продакшене обязательно используйте HTTPS и надёжное хеширование паролей. Проверяйте логи и ограничивайте попытки входа.
Конечные заметки
Подход, показанный в статье, подходит для большинства web-приложений на Spring Boot. Для API-first архитектур или интеграции с корпоративными системами возможны альтернативы (JWT, OAuth2, LDAP). Рекомендуется постепенно вводить правила безопасности, тщательно тестировать и документировать все изменения.
Краткое итоговое резюме
- Добавьте spring-boot-starter-security и необходимые зависимости.
- Создайте PasswordEncoder, UserDetailsService и SecurityFilterChain.
- Настройте доступ для публичных и защищённых страниц.
- Выполните тесты, бэкап конфигурации и примените hardening перед продом.
Похожие материалы
Pomolego — LEGO для Pomodoro и фокуса
Разделить прокрутку мыши и трекпада в macOS
Как изменить цвет курсора в macOS Monterey
Как найти пасхалку Android 14 и играть в мини-игру
Как закрыть аккаунт PayPal навсегда