Spring: Security
Важно выделить следующие определения:
Principal
. Субъект, который предполагает выполнение действия;Credentials
. Идентификационные данные, которые исползуетPrincipal
для идентификации;Authentication
. Процесс проверки валидностиCredentials
;Authorization
. Процесс, определяющий возможность для юзера выполнить конкретное действие;Secured
(item). Любой ресурс, требующий проверки доступности.
Поддерживаемые способы аутентификации довольно разнообразны, некоторые из них:
- Basic;
- Form;
- OAuth;
- X.509;
- Cookie;
- Single-Sign-On.
Некоторые допустимые места хранения Credentials
:
- DAP;
- RDBMS;
- Binary Files;
- Custom DAOs.
Сперва выполняется Authentication
с использованием Credentials
для запроса Secured
(item), который требует соответствующую Authorization
.
Наиболее часто встречающиеся роли:
ADMIN
. Полные полномочия;MEMBER
. Может изменять только доступные, согласно роли, данные;GUEST
. Может только просматривать данные. Просмотр так же с ограничением.
Конфигурирование Spring Security включает:
- Определение фильтра безопасности;
- Отпределение Spring Security контекста;
- Настройка аутентификации и авторизации.
Основные фильтры:
ChannelProcessingFilter
. Исползуется если требуется перенаправление на другой протокол. КонстантаCHANNEL_FILTER
;SecurityContextPersistenceFilter
. Используется для настройки контекста безопасности и копирует изменения из HttpSession. КонстантаSECURITY_CONTEXT_FILTER
;ConcurrentSessionFilter
. Исползуется для пакета многопоточной обработки сессий. КонстантаCONCURRENT_SESSION_FILTER
;BasicAuthenticationFilter
. ХранитAuthentication
в Security контексте. КонстантаBASIC_AUTHENTICATION_FILTER
;JaasApiIntegrationFilter
. Выполняет попытки получения JAAS объект для использования его как субъект (Subject
) вFilterChain
. КонстантаJAAS_API_SUPPORT_FILTER
;RememberMeAuthenticationFilter
. Хранит и используетAuthentication
, если не было обнаружено каких-либо изменений. КонстантаREMEMBER_ME_FILTER
;AnonymousAuthenticationFilter
. Хранит анонимнуюAuthentication
и использует ее если не было изменений. КонстантаANONYMOUS_FILTER
;ExceptionTranslatorFilter
. Преобразует Java исключения в соответствующие HTTP ошибки;FilterSecurityInterceptor
. Выкидывает ошибки в случае отсутствия доступа в URI. КонстантаFILTER_SECURITY_INTERCEPTOR
.
Изменение цепочки аутентификации
В случае XML выполняется подмена бина в соответствии с позицией:
1 | <beans:beans ...> |
В случае конфигурации через Java
1 |
|
Ограничение доступа
В случае с XML - ограничение накладывается:
1 | <beans:beans ...> |
В атрибуте access
можно указывать роли, например, ROLE_ADMIN
, ROLE_USER
, ADMIN
, …
В XML важна очередность! Наиболее ограничивающие должны быть выше.
Spring Security EL
В Spring 3 появилась возможность упрощенного указания ограничений в XML:
1 | <html use-expression="true"> |
, где:
hasRole(?)
- проверка на 1 роль;hasAnyRole(?, ?, ...)
- проверка на хотя бы 1 роль;isAnonymous()
- является ли пользователь анонимом;isAuthenticated()
- является ли пользовать аутентифицированным;hasIpAddress(?)
- является ли клиент с IP-адресом.
Условия можно комбинировать, используя and
Spring Security через Java
Заменой XML конфигурации служит Java конфигурация. Для конфигурирования следует создать класс, наследуемый от WebSecurityConfigurerAdapter
:
1 |
|
mvcMatcher
Является аналогом antMatcher
, но в большей степени рекомендован к использованию.
Spring Security Method
В качестве альтернативы XML конфигурации, Spring позволяет добавлять аннотацию @Secured
на метод, подлежащий ограничениям. Для этого к конфигурационному компоненту добавить @EnableGlobalMethodSecurity(securedEnabled=true)
:
1 |
|
Вторым вариантом аннотирования безопасности Spring является:
1 |
|
Перехват авторизации/фильтров
Spring позволяет добавить перехват Security событий. Для этого их необходимо включить:
1 |
|
Доступные аннотации:
@PreAuthorize
;@PostAuthorize
;@PreFilter
;@PostFilter
.
Для определения условий для аннотаций используется SPeL и встраивается в Spring Security ACL (Access Control List, список разрешений на объект - какой роли, какому пользователю, какой объект будет доступен).
Пример аутентификации
Для примера добавим бин с примитивной аутентификацией с использованием сочетания логин-пароль и реализованной на стороне Spring. После удачной аутентификации в Spring Security, вызываются специфические перехватчики события успешной (или не успешной) аутентификациичерез форму.
1 |
|
Стандарты аутентификации
Для аутентификации с использованием формы, Spring предполагает передачу пары логин/пароль. Плохой практикой является передача пароля в открытом виде - по-этому в Spring реализована возможность использования алгоритмов хэширования пароля. Самой простой реализацией является MD5 (в Spring существует некоторое количество готовых реализаций подсчета хэш сумм). Фактически, на стороне сервера хранится не сам пароль, а его хэш сумма и при передаче запроса на аутентификацию, проверяется соответствие именно этой хэш суммы. Пароль невозможно восстановить, можно лишь сгенерировать новую хэш-сумму (фактически, сгенерировать новый пароль). Детальнее тут.
Аутентификация с использованием выпущенного сертификата. Данный механизм представляет собой обмен данных в зашифрованном виде при наличии у клиента выпущенного (иногда личного) цифрового сертификата.
Наиболее часто применяемый в новых системах подход к аутентификации - это OAuth 2.0. Предполагает получение токена аутентификации с дальнейшее использование его в качестве подтверждения достоверности запроса. Данный механизм очень выгоден, поскольку подразумевает возможность работы как в режиме C2S (клиент-сервер), так и в режиме S2S (сервер-сервер). Инструменты аутентификации зачастую используются уже реализованные (например, KeyCloak), что высвобождает и сбрасывает ответственность за безопасность системы (часть) на техническую поддержку продукта, выполняющего аутентификацию.