Advice controller
Сохранили контроллеры от Spring MVC — сохранили и возможность использовать Advice Controller. Чтобы обрабатывать исключения можно аннотировать класс @AdviceController, а над методами разместить аннотации с типом (или несколькими типами) обрабатываемых исключений (используем @RestAdviceController как замену сочетания двух аннотаций @AdviceController и @ResponseBody). Методы должны возвращать Mono или Flux:
Контроллеры
Разрабатывая Spring WebFlux приложение, мы, как и в Spring MVC приложении, можем пользоваться контроллерами, методы которых должны возвращать Mono или Flux (коммит 1 Handle error with Advice Controller).
Каталог проектов
Просмотрите окончательную структуру проекта (на основе XML):
Просмотрите окончательную структуру проекта (на основе аннотаций):
Конфигурирование DefaultErrorWebExceptionHandler
Мы можем сконфигурировать возвращаемые данные в ответе при обработке исключения бином DefaultErrorWebExceptionHandler. Например, в ответ можно включить сообщение исключения, прописав конфигурацию в файле application.yml (коммит 2 Handle error with default ErrorWebExceptionHandler):
server:
error:
include-message: always
Пример подключения Spring Security
Посмотрим на практике, какие настройки включаются по умолчанию при добавлении в проект Spring Security.
Расширение абстрактного класса AbstractErrorWebExceptionHandler
Если же просто конфигурации DefaultErrorWebExceptionHandler нам недостаточно, мы можем создать свой собственный ErrorWebExceptionHandler. Для этого необходимо унаследоваться от AbstractErrorWebExceptionHandler. Изменим поведение метода handle, переопределив метод RouterFunction getRoutingFunction(final ErrorAttributes errorAttributes) (коммит 3 Handle error with extending AbstractErrorWebExceptionHandle):
Создание проекта и подключение зависимостей
Итак, мы готовы, чтобы написать обещанное простое приложение с регистрацией и входом в учетную запись пользователя. Используемые технологии: Spring Boot, Spring Security, Spring Data JPA, Hibernate, MySQL, JSP, Bootstrap и Docker Compose.
База данных
Чтобы выполнить проверку подлинности базы данных, необходимо создать таблицы для хранения сведений о пользователях и ролях. Пожалуйста, обратитесь к этому Ссылка на схему пользователя Spring Security . Вот сценарии MySQL для создания пользователей и роли пользователей таблицы.
4.1 Создайте таблицу “пользователи”.
4.2 Создайте таблицу “роли пользователя”.
4.3 Вставляет некоторые записи для тестирования.
INSERT INTO users(username,password,enabled) VALUES ('mkyong','123456', true); INSERT INTO users(username,password,enabled) VALUES ('alex','123456', true); INSERT INTO user_roles (username, role) VALUES ('mkyong', 'ROLE_USER'); INSERT INTO user_roles (username, role) VALUES ('mkyong', 'ROLE_ADMIN'); INSERT INTO user_roles (username, role) VALUES ('alex', 'ROLE_USER');
- Имя пользователя “mkyong”, с ролевым пользователем и ролевым администратором.
- Имя пользователя “alexa”, с ролью_пользователя.
Конфигурация безопасности Spring
Безопасность Spring как в XML, так и в аннотациях.
5.1 Создайте источник данных для подключения MySQL.
Эквивалент весенних аннотаций:
Ldap-аутентификация
Lightweight Directory Access Protocol (LDAP) — протокол аутентификации учетных записей пользователей в организациях. Позволяет определять структуру пользователей и групп пользователей, назначать им права доступа.
Дополнительную информацию вы можете получить в официальном руководстве по использованию аутентификации LDAP.
Maven-зависимость
Во-первых, это стартер для работы с базой через JPA:
Во-вторых, In-Memory база данных H2 (она удобна для учебных примеров, поскольку не нужно ставить на компьютер реальную базу):
Remember me authentication
Это встроенный механизм распознавания, благодаря которому пользователям не нужно вводить учетные данные при каждом посещении сайта.
Spring Security предлагает несколько способов реализации этого типа аутентификации — например, хеширование данных с помощью секретного ключа или хранение постоянного токена в базе данных.
Аутентификация in-memory
Для сохранения информации о пользователях и выполнения аутентификации можно использовать временную базу данных, которая остается в оперативной памяти приложения.
Это полезно при разработке и тестировании. Реальная база данных при таком подходе остается нетронутой.
Добавление зависимостей
Содержимое файла pom.xml:
Запуск docker-контейнера
Подготовьте Dockerfile для приложения Java / Spring Boot и файл docker-compose.yaml для MySQL Server.
Содержимое Dockerfile:
FROM maven:3.5-jdk-8
Содержимое docker-compose.yml:
version: '3' services: hk-mysql: container_name: hk-mysql image: mysql/mysql-server:5.7 environment: MYSQL_DATABASE: test MYSQL_ROOT_PASSWORD: hellokoding MYSQL_ROOT_HOST: '%' ports: - "3306:3306" restart: always registration-login: build: . volumes: - .:/app - ~/.m2:/root/.m2 working_dir: /app ports: - 8080:8080 command: mvn clean spring-boot:run depends_on: - hk-mysql
Перейдите в корень проекта и запустите Docker:
docker-compose up
Использование репозиториев spring data jpa
Репозитории помогают сократить шаблонный код, который необходим для реализации уровней доступа к данным в разных хранилищах — MySQL, PostgreSQL и других. В них описываются некоторые функции для создания, чтения, обновления и удаления данных из БД — например, findAll, findById, save, saveAll, delete и deleteAll.
Настройка аутентификации
Spring Security использует Form-Based-аутентификацию. Пользователь отправляет имя и пароль через форму. Сервер берет эти данные из запроса как POST-параметры.
Теперь посмотрим, как сервер хранит данные пользователей. Интересно, что они находятся не в базе, не на LDAP-сервере, а в оперативной памяти приложения. И хранятся там до тех пор, пока оно запущено. Такая аутентификация называется In-Memory authentication.
Чтобы отредактировать пользователя, необходимо заново запустить приложение. Для продакшена такой вариант не подходит, но для экспериментов в процессе разработки это простой и полезный метод.
Приложение хранит имя и пароль в памяти. Вы можете посмотреть эти данные через консоль. Чтобы каждый раз не лезть в консоль, воспользуйтесь файлом конфигурации application.yml. Зафиксируйте в нем имя и пароль пользователя.
Обработка исключений
В Spring WebFlux приложении есть несколько способов обработки исключений. Рассмотрим возможные варианты.
Определение валидатора
Входные данные будет проверять валидатор. Коды ошибок определяются в validation.properties.
Подготовка
Сгенерируйте на Spring Initializr приложение с зависимостью Web:
Напишите REST-контроллер:
@RestController public class HelloController { @GetMapping("/api/hello") public String hello(){ return "Highload"; } }
Проверьте приложение в браузере. Сейчас доступ к нему имеют все пользователи.
Подключение spring security
Добавьте Maven-зависимость, чтобы подключить Spring Security:
Репозитории
Чтобы создать реактивный репозиторий, нужно создать интерфейс, который расширяет ReactiveCrudRepository<DomainType, PrimaryKeyType>. Методы репозитория для выборки данных можно аннотировать @Query так же, как и для JPA репозиториев, чтобы извлекать данные SQL запросом, разница лишь в том, что реактивный репозиторий возвращает Mono или Flux:
Репозиторий
Пропишем в репозитории метод, который понадобится в дальнейшем:
Сервисы
В методах сервисов, обращаясь к методам репозиториев: работаем с цепочкой Mono или Flux и по тем или иным условиям при необходимости выбрасываем исключения. Хочу обратить внимание на метод switchIfEmpty издателя: выражение внутри него выполняется даже в том случае, если издатель будет не пустой (когда не нужно в результат возвращать значение из конструкции switchIfEmpty).
Создание проекта
Структура проекта должна выглядеть так:
Создание сервиса безопасности
Сервис безопасности нужен для предоставления текущего авторизованного пользователя и автоматического входа в систему после регистрации.
Создание службы пользователя
Также нужно создать службу для регистрации пользователей.
Схема и данные
Наконец, заполним базу парой пользователей с помощью data.sql (этот файл надо положить в папку resources):
Тестирование
Чтобы запустить приложение на локальном сервере MySQL, измените в application.properties «hk-mysql» на «localhost», перейдите в корневой каталог проекта и выполните команду:
mvn clean spring-boot:run
Перейдите в браузере по адресу localhost: 8080 и протестируйте приложение. Попробуйте заходить под разными пользователями, выходить, добавлять новые функции и изменять права доступа.
Исходный код нашего проекта — в репозитории на GitHub.
Управление сессией
Spring Security предоставляет механизмы для управления сеансом пользователя. Он создает эти механизмы контроля при входе в систему и уничтожает при выходе.
Для обеспечения безопасности доступны дополнительные средства, которые помогают, например, избежать отслеживания сеансов.
Шаблоны просмотра jsp (bootstrap)
Здесь достаточно трех файлов: для регистрации, входа и приветствия.
Шифрование паролей
Spring Security не ограничивается аутентификацией. Фреймворк также помогает решить проблему с безопасным хранением паролей.
Итоги
В этой статье мы познакомились с основами Spring Security и разобрали основные возможности этого фреймворка. Не ограничивайтесь теорией. Попробуйте собрать собственное простое приложение с регистрацией и аутентификацией.
Для закрепления материала также посмотрите этот тематический видеокурс: