Погружение в Spring Security для Servlet API

Spring Security — это очень мощный и гибкий фреймворк, применяемый для обеспечения безопасности приложений на платформе Java, преимущественно веб-приложений, основанных на Spring Framework. Впрочем, он может применяться и в проектах на основе Jakarta Servlet API, не использующих Spring Framework.

Spring Security предоставляет средства для реализации аутентификации, авторизации и защиты от эксплойтов. Основными компонентами Spring Security являются фильтры — экземпляры классов, реализующих интерфейс Filter. В приложении на основе Servlet API, прежде чем запрос будет обработан сервлетом, он должен пройти через цепочку фильтров, каждый из которых может модифицировать запрос и ответ, а так же при необходимости приостанавливать обработку запроса.

Важно! В нормальных условиях фильтр всегда должен продолжать процесс фильтрации при помощи chain.doFilter(request, response), в противном случае запрос никогда не достигнет своей цели — сервлета, который способен его обработать. Если же запрос не удовлетворяет каким-либо требованиям фильтра, то вызывать chain.doFilter(request, response) не надо, вместо этого нужно отправить клиенту ответ со статусом и содержимым, корректно описывающими причину отказа в обработке запроса.

Spring Security использует фильтры, зарегистрированные в контексте приложения Spring, и которые недоступны сервлет-контейнеру. Чтобы сервлет-контейнер мог использовать фильтры Spring Security, в приложении необходимо зарегистрировать компонент класса DelegatingFilterProxy, который является связующим звеном между сервлет-контейнером и контекстом приложения Spring. Если вы используете Spring Boot, то этого делать не надо — разработчики Spring Boot уже заранее сконфигурировали интеграцию Spring Security за вас.

DelegatingFilterProxy делегирует обработку запроса фильтру, зарегистрированному в контексте приложения, и в случае со Spring Security это будет FilterChainProxy — фильтр, использующий для обработки запроса цепочки фильтров безопасности — SecurityFilterChain. При обработке запроса FilterChainProxy применит все фильтры цепочки фильтров к запросу. Если в контексте приложения сконфигурировано несколько цепочек фильтров безопасности, то FilterChainProxy выберет наиболее подходящую в зависимости от параметров запроса.

Если запрос в процессе фильтрации успешно проходит все фильтры, то он достигает своей цели — сервлета, который сможет его обработать, в случае со Spring Framework это будет DispatcherServlet.

Настройка цепочек фильтров безопасности

Для включения поддержки Spring Security в приложении один из конфигурационных классов нужно отметить аннотацией @EnableWebSecurity:

Впрочем, если вы используете Spring Boot, то делать вам это опять же не требуется.

Для настройки цепочки фильтров безопасности необходимо зарегистрировать в контексте приложения компонент типа SecurityFilterChain, создать его можно из экземпляра HttpSecurity, который зарегистрирован в контексте приложения после включения поддержки Spring Security.

По умолчанию в Spring Boot цепочка фильтров безопасности сконфигурирована с поддержкой Basic-аутентификации и аутентификации при помощи формы.

Если требуется сконфигурировать несколько цепочек фильтров безопасности, то их нужно регистрировать в контексте приложения с разными приоритетами:

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