Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Краткий экскурс в Spring Security (core)

Краткий экскурс в Spring Security (core)

Слайды вводной лекции о фреймворке Spring Security

Vladimir Plizga

September 15, 2020
Tweet

More Decks by Vladimir Plizga

Other Decks in Programming

Transcript

  1. Краткий экскурс
    в Spring Security
    (core)

    View full-size slide

  2. 2
    1. Теория
    2.

    3. Практика
    3. Применение
    План

    View full-size slide

  3. 1. Теория
    Введение
    О чём вообще пойдёт речь?

    View full-size slide

  4. Spring Security — это:
    ✓ Какая-то приблуда для безопасности
    ✓ Очередной фреймворк зоопарка Spring
    ✓ “Коробочное” решение для защиты
    приложений от рисков ИБ
    5
    Интуитивное представление: ОК ✔

    View full-size slide

  5. “Spring Security is a powerful
    and highly customizable
    authentication and access-control
    framework”
    6
    По мнению
    авторов
    Ни слова про
    light-weight

    View full-size slide

  6. Аутентификация
    Отвечает на вопрос:
    “Ты ли это?”
    Имеет дело с логинами
    и паролями.
    Устраняем любимую путаницу
    Авторизация
    Отвечает на вопрос:
    “Можно ли тебе сюда?”
    Имеет дело с правами,
    ролями, доступами...
    7
    Наша главная
    тема сегодня
    Но начнём
    с этой

    View full-size slide

  7. 1. Теория
    Авторизация
    Она же: контроль доступа

    View full-size slide

  8. Вместо disclaimer’а
    9
    ○ Пробежимся по верхушкам
    ○ Только для общего представления
    ○ Без примеров и конкретики

    View full-size slide

  9. Интерфейс AccessDecisionManager
    10
    public interface AccessDecisionManager {
    void decide(Authentication authentication, Object object,
    Collection configAttributes)
    throws AccessDeniedException, InsufficientAuthenticationException;
    boolean supports(ConfigAttribute attribute);
    boolean supports(Class> clazz);
    }

    View full-size slide

  10. Интерфейс AccessDecisionManager
    11
    ✢ Центральный компонент авторизации
    ✢ Опрашивает других участников выбора
    "пускать или нет"
    ✢ Обычно делегирует имплементациям
    интерфейса AccessDecisionVoter

    View full-size slide

  11. Интерфейс AccessDecisionVoter
    12
    public interface AccessDecisionVoter {
    int ACCESS_GRANTED = 1;
    int ACCESS_ABSTAIN = 0;
    int ACCESS_DENIED = -1;
    int vote(Authentication authentication, S object,
    Collection attributes);
    boolean supports(ConfigAttribute attribute);
    boolean supports(Class> clazz);
    }

    View full-size slide

  12. Авторизация в веб-приложениях
    13
    ✢ Включается через @EnableWebSecurity
    ✢ Работает как 1 фильтр FilterChainProxy
    ✢ Делегирует внутренним фильтрам (бинам)

    View full-size slide

  13. 14
    Фильтры Spring Security
    https://spring.io/guides/topicals/spring-security-architecture

    View full-size slide

  14. Фильтры собираются в цепочки
    15
    ✢ Цепочек может быть несколько
    ✢ На каждый запрос срабатывает только одна
    ✢ В spring-boot-starter-security из коробки 6 цепочек:
    ○ Для статики
    ○ Для ошибок, для ...
    ○ Для всего остального
    11 фильтров

    View full-size slide

  15. Цепочки фильтров Spring Security
    16
    https://spring.io/guides/topicals/spring-security-architecture

    View full-size slide

  16. А что-нибудь покруче?
    Есть кое-что...
    17

    View full-size slide

  17. Авторизация на уровне методов
    18
    ✢ Включается через аннотацию:
    @EnableGlobalMethodSecurity(securedEnabled=true)
    ✢ Работает как прокси (можно на AOP)
    ✢ При нарушении доступа выбрасывает:
    AccessDeniedException

    View full-size slide

  18. Варианты авторизации для методов
    19
    @Service
    public class MyService {
    @Secured("ROLE_USER")
    public String secure() {
    return "Hello Security";
    }
    }
    @PreAuthorize("hasRole('ADMIN')")
    @PostAuthorize("hasPermission(filterObject, 'read')")
    SpEL
    Но должно же у них быть
    что-то общее?

    View full-size slide

  19. 1. Теория
    Устройство
    Как это работает

    View full-size slide

  20. SecurityContext
    Краеугольный камень Spring Security.
    Содержит саму “аутентификацию”.
    21

    View full-size slide

  21. Интерфейс SecurityContext
    22
    public interface SecurityContext extends Serializable {
    Authentication getAuthentication();
    void setAuthentication(Authentication authentication);
    }
    Та самая “аутентификация”

    View full-size slide

  22. Интерфейс Authentication
    23
    public interface Authentication extends Principal, Serializable {
    Collection extends GrantedAuthority> getAuthorities();
    Object getCredentials();
    Object getDetails();
    Object getPrincipal();
    boolean isAuthenticated();
    void setAuthenticated(boolean isAuthenticated)
    throws IllegalArgumentException;
    }

    View full-size slide

  23. Что содержит Authentication
    24
    principal — это обычно пользователь
    (наследник UserDetails; у нас это карта)
    credentials — это обычно пароль (String)
    authorities — список разрешений/доступов
    details — что угодно (IP, свойства и т.п.)
    authenticated — признак успешной проверки

    View full-size slide

  24. SecurityContext доступен отовсюду
    25
    ✢ Напрямую через SecurityContextHolder:
    SecurityContext context = SecurityContextHolder.getContext();
    Authentication authentication = context.getAuthentication();
    assert authentication.isAuthenticated();
    ✢ Опосредованно через аннотации:
    @RequestMapping("/foo")
    public String foo(@AuthenticationPrincipal User user) {
    // do stuff with user
    }
    почти

    View full-size slide

  25. SecurityContext доступен отовсюду
    26
    ✢ Опосредованно из сервлет-контейнера:
    @RequestMapping("/foo")
    public String foo(Principal principal) {
    Authentication authentication = (Authentication) principal;
    User user = (User) authentication.getPrincipal();
    // do stuff with user
    }
    почти
    Но откуда он попадает
    во все эти места?

    View full-size slide

  26. “Spring Security is fundamentally thread bound
    because it needs to make
    the current authenticated principal available
    to a wide variety of downstream consumers”
    27
    По словам
    авторов

    View full-size slide

  27. “Fundamentally thread bound”
    28
    ✢ В каждом потоке свой SecurityContext
    ✢ Как правило, за нас это делает Spring Security
    ✢ Но иногда можно/нужно самим:
    @Configuration
    public class ApplicationConfiguration extends AsyncConfigurerSupport {
    @Override
    public Executor getAsyncExecutor() {
    return new DelegatingSecurityContextExecutorService(newFixedThreadPool(5));
    }
    }
    А как же реактивщина?

    View full-size slide

  28. Reactive Spring Security ⚛
    29
    ✢ ReactiveSecurityContextHolder
    ✢ Под капотом использует
    reactor.util.context.Context
    ✢ Для веб-приложений работает за счёт
    ReactorContextWebFilter
    ✢ Нуждается в @EnableWebFluxSecurity
    и @EnableReactiveMethodSecurity

    View full-size slide

  29. 1. Теория
    Аутентификация
    “Ты ли это?”

    View full-size slide

  30. Пара слов о менеджерах
    31

    View full-size slide

  31. Интерфейс AuthenticationManager
    32
    public interface AuthenticationManager {
    Authentication authenticate(Authentication authentication)
    throws AuthenticationException;
    }
    Является входной точкой во всю логику
    аутентификации Spring Security

    View full-size slide

  32. Варианты ответа метода authenticate()
    33
    ✢ Объект Authentication (authenticated=true)
    ⇒ Всё ОК ✅
    ✢ Исключение AuthenticationException
    ⇒ Пшёлвон ⛔
    ✢ null, просто null
    ⇒ Я не в курсе, спроси другого ‍♂

    View full-size slide

  33. Класс ProviderManager
    34
    ✢ Основная имплементация для
    AuthenticationManager’а
    ✢ Делегирует набору AuthenticationProvider’ов
    ✢ Швыряет ProviderNotFoundException,
    если не находит подходящего провайдера

    View full-size slide

  34. AuthenticationManager AuthenticationProvider
    35
    Вася
    Менеджер

    View full-size slide

  35. ProviderManager может иметь родителя
    36
    https://spring.io/guides/topicals/spring-security-architecture

    View full-size slide

  36. ProviderManager
    умеет рассылать
    события
    37

    View full-size slide

  37. Как создать AuthenticationManager’а
    38
    Способы:
    ✢ С помощью AuthenticationManagerBuilder ‍♂
    ✢ Вручную, с нуля
    Области:
    ✢ Глобально на всё приложение
    ✢ Локально на заданную часть

    View full-size slide

  38. Пример 1: локально, builder’ом
    39
    @Configuration
    public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
    @Autowired
    DataSource dataSource;
    @Override
    public void configure(AuthenticationManagerBuilder builder) {
    builder.jdbcAuthentication().dataSource(dataSource)
    .withUser("dave").password("secret")
    .roles("USER");
    }
    }

    View full-size slide

  39. Пример 2: глобально, с нуля
    40
    @Bean
    public AuthenticationManager globalAuthenticationManager(
    PasswordAuthenticationProvider passwordAuthenticationProvider,
    PinAuthenticationProvider pinAuthenticationProvider) {
    var providerManager = new ProviderManager(List.of(
    passwordAuthenticationProvider,
    pinAuthenticationProvider));
    // всякие манипуляции с этим объектом
    return providerManager;
    }
    Перекроет бин, поставляемый
    spring-boot-starter-security

    View full-size slide

  40. Словарный запас Spring Security
    41
    ProviderManager
    AuthenticationManager
    AuthenticationProvider
    имплементирован
    делегирует
    подчинённый

    View full-size slide

  41. А что делать с учётками?
    Под интерфейс их!
    42

    View full-size slide

  42. Интерфейс UserDetailsService
    43
    public interface UserDetailsService {
    UserDetails loadUserByUsername(String username)
    throws UsernameNotFoundException;
    }
    Является "мостом" между прикладным
    хранилищем учётных данных и Spring Security

    View full-size slide

  43. Интерфейс UserDetailsService
    44
    Имеет реализации в Spring Security:
    ✢ JDBC
    ✢ In-memory
    ✢ Кэширующая прослойка
    ✢ …
    ✢ И легко запилить свою

    View full-size slide

  44. UserDetails
    Абстрагирует фреймворк
    от прикладных моделей пользователей
    45

    View full-size slide

  45. Интерфейс UserDetailsService
    46
    public interface UserDetails extends Serializable {
    Collection extends GrantedAuthority> getAuthorities();
    String getPassword();
    String getUsername();
    boolean isAccountNonExpired();
    boolean isAccountNonLocked();
    boolean isCredentialsNonExpired();
    boolean isEnabled();
    }
    * Есть реализация
    в Spring Security
    (класс User)

    View full-size slide

  46. Превратности контракта UserDetails
    47
    ✢ Метод getUserName() никогда не должен
    возвращать null.
    ✢ Метод getPassword() может вернуть null:
    ○ Критичные данные могут стираться из памяти
    после успешной аутентификации.
    ○ См. CredentialsContainer#eraseCredentials
    Кстати, о паролях...

    View full-size slide

  47. Интерфейс PasswordEncoder
    48
    public interface PasswordEncoder {
    String encode(CharSequence rawPassword);
    boolean matches(CharSequence rawPassword, String encodedPassword);
    }
    (Де)Кодирует пароли для безопасного хранения
    https://docs.spring.io/spring-security/site/docs/5.2.6.RELEASE/reference/htmlsingle/#core-services-password-encoding

    View full-size slide

  48. Какой алгоритм самый стойкий?
    В перспективе ‒ никакой!
    49

    View full-size slide

  49. DelegatingPasswordEncoder
    ✔ Учитывает современные требования ИБ
    ✔ Обеспечивает миграцию на новые
    алгоритмы
    ✔ Поддерживает старые приложения
    50

    View full-size slide

  50. Класс DelegatingPasswordEncoder
    51
    Хранит пароли в формате “{id}encodedPassword”:
    ✢ id ‒ идентификатор алгоритма
    ✢ encodedPassword ‒ кодированный пароль
    (может включать метаданные)

    View full-size slide

  51. Примеры хэшей от слова “password”
    52
    {bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
    {pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc
    {sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
    {argon2}$argon2id$v=19$m=4096,t=3,p=1$PvvIwF0BSb/ycgO51cSkPg$xizQ/EyAyLYJb+/E+KiJf1bg5RUdcUUttly0bA6MjUU
    {noop}password

    View full-size slide

  52. Класс DelegatingPasswordEncoder
    53
    ✢ Используется в Spring Security по умолчанию
    ✢ Умеет “совершенствовать” хэши паролей
    ✢ Удобно создавать через
    PasswordEncoderFactories

    View full-size slide

  53. Алгоритмы хэширования паролей
    54
    SHA-1, SSHA (ldap), SHA-256, MD-5, MD-4
    Не безопасны, не рекомендованы, вызывают
    головную боль и предупреждения в IDE
    ➖ scrypt, bcrypt
    Широко распространённые варианты
    (не только в экосистеме JVM)
    pbkdf2, argon2
    Современные намеренно-ресурсоёмкие алгоритмы

    View full-size slide

  54. Алгоритм Argon2 в Spring Security
    55
    ✢ Реализован в org.bouncycastle:bcprov-jdk15on:1.64
    ✢ Используется через класс Argon2PasswordEncoder
    ✢ Генерирует соль из SecureRandom
    ⇒ один пароль всякий раз даёт разные хэши

    View full-size slide

  55. Argon2 BCrypt
    56 https://virgo.ftc.ru/x/YYwDOQ

    View full-size slide

  56. 1. Теория
    Заключение
    Резюме и выводы

    View full-size slide

  57. Кратко о Spring Security в целом
    58
    ✢ Помогает с аутентификацией и авторизацией
    ✢ Обеспечивает гибкость через интерфейсы
    ✢ Состоит из модулей (core, web, config, ldap, ...)

    View full-size slide

  58. Резюме по авторизации
    59
    ✢ Работает в веб-приложениях за счёт фильтров
    ✢ Умеет защищать методы через прокси-обёртки
    ✢ Основные классы:
    ○ @EnableWebSecurity, @EnableGlobalMethodSecurity
    ○ AccessDecisionManager, AccessDecisionVoter
    ○ @PreAuthorize, @PostAuthorize

    View full-size slide

  59. Резюме по аутентификации
    60
    ✢ Является “скелетом” для подключения разных
    механизмов проверки
    ✢ Предоставляет средства работы с паролями
    ✢ Основные классы:
    ○ Authentication, AuthenticationManager
    ○ SecurityContext, SecurityContextHolder
    ○ UserDetails, UserDetailsService

    View full-size slide

  60. Остальное
    здесь
    ✢ Описание
    ✢ Sequences
    ✢ Подсказки
    ✢ Дроплеты
    ✢ ...
    61
    https://virgo.ftc.ru/x/YYwDOQ

    View full-size slide

  61. 2. Применение
    Как всё это выглядит на деле

    View full-size slide

  62. Show me the code!
    64

    View full-size slide

  63. Спасибо!
    Вопросы?
    Материалы будут разосланы
    отдельным письмом
    65

    View full-size slide

  64. Credits
    Special thanks to all the people who made and
    released these awesome resources for free:
    ✢ Presentation template by SlidesCarnival
    ✢ Photographs by Unsplash
    66

    View full-size slide