Основы Spring security

от автора

Введение

Доброго времени суток, друзья!

В данной статье я постараюсь довольно кратко и подробно описать то, как работает spring security изнутри. Статья будет вводная, и будет содержать в основном теорию.

Собственно. Что же такое этот Spring Security?

Spring Security — это главный фреймворк который предоставляет механизмы построения систем аутентификации и авторизации. Помимо этого он даёт возможность обеспечения безопасности для приложений, созданных на spring’e.

Мы поняли, что он обеспечивает безопасность и даёт возможность аутентификации и авторизации, то что это такое?…

Аутентификация — это проверка личности пользователя, то есть логин+пароль или jwt или к примеру OAuth2. Если проще, то аутентификация отвечает на вопрос: «Докажи что ты это ты?»
Авторизация — это проверка прав доступа, то есть то, что конкретный пользователь может делать. Например, обычный пользователь может посмотреть список продуктов, добавить продукты в корзину и сделать заказ. А в это время менеджер может сделать всё то же самое, что и обычный пользователь, но и добавить и/или убрать каике то товары из магазина. Снова для простоты, авторизация отвечает на вопрос: «Что тебе можно делать?»

Далее возникает вопрос: а как оно работает?
Ответ на этот вопрос довольно прост. Spring Security перехватывает каждый HTTP‑запрос с помощью специальных Servlet Filter‑ов, которые встраиваются в жизненный цикл HTTP‑запроса до того, как он доберётся до контроллера.

Чуть ниже будет картинка как работает эта магия, но ничего магического там нет, всё на себя берёт проксирование. И чтобы понять эту картинку, нужно узнать пару новых вещей:

DelegatingFilterProxy — это такой своеобразный мост между Servlet Api и Spring context. Он позволяет перенаправить входящие HTTP‑запросы на обработку компонентами, которыми управляет сам Spring.
FilterChainProxy — это специальный связующий фильтр (прокси), который управляет всеми цепочками фильтров.
SecurityFilterChain — по сути это цепочка обработки HTTP‑запроса, то есть каждый запрос проходит определённые проверки, например на определённые url может заходить только админ и тп.

Работа Spring Security

Работа Spring Security

После того как пользователь успешно пройдёт аутентификацию Spring Security сохраняет пользователя в SecurityContext:

SecurityContext context = SecurityContextHolder.getContext();//Объект аутентификаации который содержит информацию о вошедешем пользователеAuthentication auth = context.getAuthentication();//Получение уникального имени пользователяString username = auth.getName();//Получение списка ролей, выданных пользователюCollection<? extends GrantedAuthority> roles = auth.getAuthorities();

Важно добавить, что сам SecurityContextHolder по умолчанию использует ThreadLocal — это значит что контекст живёт в рамках одного потока запросов. Это одновременно и хорошо и не очень.
Это хорошо потому что — данные о пользователе можно получить из любого сервиса или репозитория без необходимости передачи Authentication через аргументы всех вызовов, а также привязка к потоку гарантирует, что запросы пользователей не смешаются между собой и пользователь А не увидит данные пользователя Б.
А не очень хорошо потому что при каких либо асинхронных фоновых задач, SecurityContext не будет скопирован в новый поток, что может вести за собой падение методов с @PreAuthorize или @Sheduled, а также могут возникнуть ошибки при работе с базами данных, пустыми отчётами и так далее.
Дабы избежать неприятных моментов, можно изменить стратегию хранения SecurityContextHolder, чтобы адаптировать под свои нужды, но это уже как-нибудь потом.

Спасибо всем кто дочитал эту статью, надеюсь она оказалась полезной и информативной. Если эту статью из интереса прочитает более опытный человек, то с радостью приму критику и учту в дальнейших статьях!

ссылка на оригинал статьи https://habr.com/ru/articles/1054852/