Эта статья является переводом статьи по подготовке к Spring Professional Certification.
В ней будет рассмотрена тема Spring Security и основные вопросы по ней.
Ее также можно использовать для подготовки к собеседованию.
↓ Остальные статьи доступны по ссылкам в оглавлении ↓
- Внедрение зависимостей, контейнер, IoC, бины
- AOP (аспектно-ориентированное программирование)
- JDBC, транзакции, JPA, Spring Data
- Spring Boot
- Spring MVC
- Spring Security
- REST
- Тестирование
Сами вопросы:
Аутентификация — процесс верификации пользователя компьютерной системы.
Вот как он происходит в Spring:
- Полученные пароль и имя пользователя преобразуются в экземпляр UsernamePasswordAuthenticationToken. Он реализует интерфейс Authentication.
- Токен передается объекту
AuthenticationManager
для проверки - В случае удачной проверки AM возвращает заполненный объект
Authentication
- Устанавливается security context, с помощью вызова
SecurityContextHolder.getContext().setAuthentication(...)
Авторизация — это процесс удостоверения в том, что у пользователя есть роль, требуемая чтобы сделать какое-либо действие. При авторизации проверяется, есть ли у вас соответствующие права на доступ к ресурсу.
Процесс:
- По принципалу(principal) пользователя отображается его роль
- Роль пользователя сверяется с ролью ресурса
Сначала происходит аутентификация, а потом — авторизация.
Используя Spring AOP proxy, которые наследуются от класса AbstractSecurityInterceptor.
Применяется для методов вызывающих авторизацию.
Веб-инфраструктура в Security основана на servlet-фильтрах.
Первым делом конфигурируется фильтр DelegatingFilterProxy
. Он делегирует запрос в FilterChainProxy
.
FilterChainProxy
— это бин, который принимает в конструкторе один или несколько SecurityFilterChain
.
SeccurityFilterChain
сравнивает URL в запросе со списком фильтров.
SecurityContextHolder
— содержит и предоставляет доступ к SecurityContext в приложении.
SecurityContext
— дефолтная реализация Spring Security содержащая объект Authentication.
Authentication
— предоставляет токен для запроса аутентификации или для принципала, который прошел аутентификацию. Также содержит список полномочий, к которым получил доступ принципал.
GrantedAuthority
— содержит полномочия выданные прошедшему проверку принципалу.
UserDetails
— содержит информацию о пользователе: пароль, логин, полномочия. Эта информация используется для создания объекта Authentication после удачной аутентификации.
UserDetailsService
— этот сервис извлекает информацию о пользователе из хранилища(память программы, бд, и т.п.) и кладет ее в UserDetails.
Класс DelegatingFilterProxy
— это класс, который реализует интерфейс javax.Servlet.Filter
.
Это специальный фильтр, который делегирует работу другим бинам, которые также являются фильтрами.
Цепочка фильтров имплементит интерфейс SecurityFilterChain
. Имплементацией, поставляемой Spring Security, является DefaultSecurityFilterChain.
Конструктор DSFC принимает несколько параметров. Первый параметр — request matcher. Остальные параметры — это фильтры, реализующие интерфейс servlet.Filter. Вот все фильтры, принимаемые DSFC:
ChannelProcessingFilter
SecurityContextPersistenceFilter
ConcurrentSessionFilter
- Любой auth. фильтр:
UserNamePasswordAuthenticationFilter
/CasAythenticationFilter
/BasicAuthenticationFilter
SecurityContextHolderAwareRequestFilter
JaasApiIntegrationFilter
RemeberMeAuthenticationFilter
AnonymusAuthenticationFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
Основной объект — это SecurityContextHolder
. Это место, где хранятся детали о текущем security context, например детали принципала который в текущий момент пользуется приложением. По умолчанию для хранения используется ThreadLocal
.
//получение SecurityContext
SecurityHolderContext.getContext()
Объект, возвращаемый методом getContext()
это SecurityContext
. Он позволяет получать и устанавливать объект Authentication
.
Authentication
представляет следующие свойства:
- Коллекцию полномочий выданных принципалу
- Данные для удостоверения пользователя(логин, пароль)
- Details — доп. информация, если она нужна. Может быть равно null
- Принципал
- Authentication flag — boolean переменная, которая показывает успешно ли прошел проверку принципал
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
//игнорирование всех запросов на /resources
.antMatchers("/resources/**").permitAll()
//для остальных запросов требуется одна из 2 ролей
.antMatchers("/").hasAnyRole("ANONYMOUS", "USER")
.antMatchers("/login)*").hasAnyRole("ANONYMOUS", "USER")
.antMatchers("/logoutr").hasAnyRole("ANONYMOUS", "USER")
//запрос на ресурсы ниже требуют роль ADMIN
.antMatchers("iadmin/*").hasRole("ADMIN")
.antMatchers("/events/").hasRole("ADMIN")
}
Это выражение означает “любой”.
Есть 2 вида:
*
— перехватывает только на том уровне, на котором используется.
Например, паттерн “/orders/*” проверит права пользователя, если пользователь перейдет по
/orders/aliens или /orders/1, но не /orders/alien/1.
**
— перехватывает на всех уровнях.
Будут проверены любые запросы, /orders/aliens, /orders/1, /orders/alien/1.
Потому что antMatcher(“/service”)
сопоставляет путь запроса только с “/service”
, в то время как mvcMatcher(“/service”)
сопоставляет с “/service”
, “/service.html”
, “/service.abc”.
Да, поддерживает. Для хэширования существует интерфейс PasswordEncoder
, который содержит только один метод:
static PasswordEncoder createDelegatingPasswordEncoder()
, который возвращает DelegatePasswordEncoder
, настроенный по умолчанию.
Соль используется для вычисления хеш-значения пароля. Это последовательность рандомных чисел, которые используются для преобразования текстового пароля в хеш. Соль хранится в открытом виде рядом с хеш-паролем и может использоваться в дальнейшем при конвертации чистого пароля в хеш при новом логине пользователя.
Spring Security поддерживает защиту отдельных методов в бинах(например, в контроллерах). Это дополнительный слой защиты для приложения.
Ее требуется указать явно, используя аннотацию @EnableGlobalMethodSecurity
.
Эта аннотация основана на JSR-250.
@RolesAllowed
позволяет настроить доступ к методам(например, в классе-контроллере) с помощью ролей.
Пример: @RolesAllowed(“ADMIN”)
будет пропускать только пользователей с ролью ADMIN
Для использования нужно установить @EnableGlobalMethodSecurity(jsr250Enabled=true)
на @Configuration классе + нужно чтобы эта аннотация была в classpath.
@PreAuthorize
позволяет настроить доступ к методу используя SpEL.
Для использования нужно установить @EnableGlobalMethodSecurity(prePostEnabled=true)
Используется сквозная функциональность, с помощью Spring AOP(прокси-объекты).