Щоб зрозуміти, як працюють системи безпеки, треба чітко розрізняти два ключові поняття: аутентифікація і авторизація. Ми вже почали розмову про них, але тепер розставимо акценти, щоб ви в них не плутались і запам'ятали раз і назавжди.
Уявіть, що ви прийшли в дім до друга. Перше, що ви робите — це дзвоните у дзвінок. Друг дивиться у вічко, перевіряючи, що це ви, а не якийсь незрозумілий тип. Це і є аутентифікація — перевірка, що ви той, за кого себе видаєте. А потім друг вирішує: "Окей, я дозволю тобі зайти у вітальню, а в спальню — ні-ні!" Це — авторизація.
В контексті додатків і систем безпеки:
- Аутентифікація відповідає на питання: "Хто ти взагалі такий?" Ми перевіряємо підлинність користувача: логін, пароль, іноді відбиток пальця, або навіть танець з бубном.
- Авторизація — інший рівень: "Окей, я знаю, хто ти, але що ти можеш робити в моєму додатку?" Тут все прив'язано до прав доступу й ролей.
Як працює аутентифікація в Spring Security?
Spring Security надає широкий спектр інструментів для реалізації аутентифікації. Є два ключові аспекти: визначення способу аутентифікації і збереження даних про користувачів. Давайте розберемося.
Типи аутентифікації
- Форм-логін — найпростіший метод. Користувач вводить ім'я і пароль у HTML-формі, дані відправляються на сервер і перевіряються. Якщо все ок — доступ відкрито.
Приклад налаштування:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() // Всі запити вимагають аутентифікації .and() .formLogin() // Увімкнути аутентифікацію через форму .loginPage("/login") // Вказання шляху до кастомної сторінки логіна .permitAll(); } } - Basic Authentication — проста аутентифікація з передачeю логіна/пароля в кожному запиті (поганий варіант для продакшену без HTTPS).
- Token-based Authentication (наприклад, JWT) — замість передачі логіна/пароля на кожному кроці, ми використовуємо токен, який підтверджує аутентифікацію.
- OAuth2/OpenID Connect — складніша схема, про яку ми поговоримо далі в курсі.
Де зберігати користувачів і паролі?
- In-memory — зручно для тестування. Все зберігається в оперативці, зникає при перезапуску.
Приклад:
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user").password("{noop}password").roles("USER") .and() .withUser("admin").password("{noop}admin").roles("ADMIN"); } - У базі даних — реальний спосіб для продакшену. Ми використовуємо
UserDetailsService, щоб надати інформацію про користувачів з бази даних. - LDAP/Active Directory — інтеграція з корпоративними системами.
Як працює авторизація в Spring Security?
Ми розібралися, хто наш користувач (аутентифікація), але тепер наступне питання: "А що йому можна робити?"
Дозволи на основі ролей (Role-based Access Control, RBAC)
Spring Security використовує концепцію ролей для управління доступом. У користувача можуть бути ролі, наприклад, ROLE_USER або ROLE_ADMIN. На основі цих ролей ми конфігуруємо доступ до різних частин додатку.
Приклад:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN") // Лише роль ADMIN
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN") // Ролі USER і ADMIN
.anyRequest().authenticated();
}
Авторизація на рівні методів
Іноді треба обмежити доступ не до URL, а до конкретних методів у вашому коді. Наприклад, тільки адміністратор може видаляти користувачів.
Приклад з анотацією @PreAuthorize:
@Service
public class UserService {
@PreAuthorize("hasRole('ADMIN')") // Лише адміністратор може
public void deleteUser(String username) {
// Логіка видалення користувача
}
}
Реальні сценарії
Сценарій 1: Тільки зареєстровані користувачі можуть переглядати профілі
Ми хочемо, щоб сторінка профілю була доступна тільки аутентифікованим користувачам. Це легко налаштувати:
http
.authorizeRequests()
.antMatchers("/profile/**").authenticated() // Лише аутентифіковані
.and()
.formLogin();
Сценарій 2: Адміністратор може додавати нові дані, але не змінювати
У вашій бізнес-логіці адміністратори можуть додавати записи, але зміни — це прерогатива менеджерів. Використаємо метод-настроювання:
@Service
public class DataService {
@PreAuthorize("hasRole('ADMIN')")
public void addData(Data data) {
// Логіка додавання даних
}
@PreAuthorize("hasRole('MANAGER')")
public void updateData(Data data) {
// Логіка оновлення даних
}
}
Поширені помилки новачків
Одна з найчастіших помилок при налаштуванні аутентифікації/авторизації — використання неправильного порядку правил. Наприклад, якщо ви вкажете anyRequest().permitAll() перед іншими правилами, ваш додаток дозволить доступ всім.
Приклад неправильного порядку:
http
.authorizeRequests()
.anyRequest().permitAll() // Відкриває все для всіх!
.antMatchers("/admin/**").hasRole("ADMIN");
Правильний порядок:
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().permitAll();
Тож будьте уважні з порядком правил!
Як це застосовується в реальному житті?
Ми будуємо додаток, в якому безпека — невід'ємна частина. Навички налаштування ролей і аутентифікації знадобляться вам скрізь, від простого інтернет-магазину до складних систем управління фінансами. Наприклад, якщо ви розробляєте додаток для банку, вам доведеться враховувати не тільки ролі користувачів, але й рівні їх доступу, складні системи токенів і багато іншого.
Spring Security достатньо гнучкий, щоб впоратися з будь-яким завданням. Розуміння основ аутентифікації і авторизації — ваш перший крок до розробки дійсно захищених додатків.
На наступній лекції ми більш детально розглянемо анотації Spring Security, такі як @Secured, @PreAuthorize та інші, які допоможуть вам керувати безпекою на рівні коду.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ