JavaRush /Курси /Модуль 5. Spring /Анотація @EnableWebSecurity і її призначення

Анотація @EnableWebSecurity і її призначення

Модуль 5. Spring
Рівень 17 , Лекція 3
Відкрита

Spring Security — дійсно потужний інструмент, але щоб почати використовувати його у вашому проєкті, треба увімкнути механізм безпеки. Анотація @EnableWebSecurity, як можна здогадатися з назви, саме для цього й служить.

У двох словах, @EnableWebSecurity:

  • вмикає можливість використання Spring Security у вашому додатку.
  • підключає конфігурації безпеки через клас WebSecurityConfigurerAdapter або напряму через SecurityFilterChain.
  • ініціалізує фільтри Spring Security для обробки всіх вхідних HTTP-запитів.

Без її додавання Spring Security буде в проєкті як музейний експонат — красиво, але не дуже корисно. Давайте подивимось, як вона працює і чому вона така важлива.


Що відбувається після додавання @EnableWebSecurity?

Знаєте, що стається, коли додаєте @EnableWebSecurity в код? Spring Security прокидається і починає охороняти ваш додаток! Подивимось під капот цієї магії:

  1. Spring створює ланцюжок фільтрів безпеки — такий собі КПП для всіх вхідних запитів. Кожен запит тепер проходить через цю охоронну систему, перш ніж потрапити в ваш додаток.
  2. Spring Security відразу вмикає базовий захист — ніби ставить замки на всі двері. За замовчуванням усі HTTP-ресурси стають закритими, і без правильних "ключів" (аутентифікації) до них не добратись.
  3. І найцікавіше — ви можете налаштувати цю систему під свої потреби! Хочете додати власні перевірки? Використовуйте SecurityFilterChain.

Якщо цікавить історія, раніше для цього використовували WebSecurityConfigurerAdapter (хоча з версії 5.7 він вже вважається антикваріатом).


Основи конфігурації з @EnableWebSecurity

Ось приклад мінімальної конфігурації безпеки:


import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    // Поки конфігурація порожня, але вся безпека вже увімкнена!
}

Якщо запустити цей додаток і спробувати звернутися до будь-якого URL ваших ресурсів чи контролерів, ви помітите, що Spring Security автоматично перенаправить вас на сторінку входу. Це стандартна поведінка, що надається "за замовчуванням".

Кастомізація конфігурації

Додамо трохи корисної кастомізації. Для цього ми можемо включити перевизначення налаштувань через метод SecurityFilterChain:

Приклад з кастомними правилами:


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests() // Налаштовуємо авторизацію запитів
                .antMatchers("/public/**").permitAll() // Дозволяємо доступ до всіх URL, що починаються з /public
                .anyRequest().authenticated() // Всі інші запити потребують аутентифікації
            .and()
            .formLogin() // Вмикаємо стандартну форму логіну
                .loginPage("/login") // Кастомна сторінка логіну
                .permitAll()
            .and()
            .logout() // Вмикаємо стандартний logout
                .permitAll();
        return http.build();
    }
}

Розберімося, що робить цей код:

  1. Обмеження доступу по URL: методи antMatchers дозволяють визначати доступ на основі певних URL. Наприклад, усі запити до /public дозволені без аутентифікації.
  2. Форма входу: ми кастомізували стандартну форму входу, вказавши нашу сторінку логіну через метод loginPage. Тепер замість дефолтної сторінки логіну користувачі бачитимуть ваш кастомний інтерфейс.
  3. Вихід: ми дозволяємо будь-якому користувачу виконувати logout.

Після додавання цієї конфігурації, наш додаток буде захищений більш змістовно, ніж з базовою конфігурацією Spring Security.


Навіщо потрібен WebSecurityConfigurerAdapter?

Ми вже згадували, що до версії Spring Security 5.7 кастомізація конфігурації безпеки зазвичай виконувалась через наслідування класу WebSecurityConfigurerAdapter. Ось як це виглядало:


import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
            .and()
            .logout()
                .permitAll();
    }
}

Якщо ви досі побачите такий підхід у старому коді — не лякайтеся. Проте краще звикати до використання SecurityFilterChain, бо цей спосіб є більш сучасним.


Приклади налаштування базової безпеки

1. Простий приклад, де всі сторінки захищені:


@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
            .and()
            .formLogin() // Увімкнення форми логіну
            .and()
            .httpBasic(); // Це додає підтримку базової аутентифікації
        return http.build();
    }
}

Тепер при спробі отримати доступ до будь-якого ресурсу, користувач повинен або ввести логін/пароль у браузері, або автентифікуватись через HTTP Basic.

2. Приклад з публічними ресурсами:


@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/css/**", "/js/**", "/images/**").permitAll() // Відкриваємо статичні ресурси
                .antMatchers("/", "/home").permitAll() // Відкриваємо головну сторінку
                .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
            .and()
            .logout()
                .permitAll();
        return http.build();
    }
}

Цей приклад дозволяє переглядати певні публічні ресурси (наприклад, статику або головну сторінку), але захищає все інше.


Часті помилки та їх усунення

  1. Помилка: заблоковані всі ресурси, включаючи логін. Якщо ви налаштуєте все неправильно, то можете випадково заблокувати навіть доступ до вашої сторінки входу. Перевірте, щоб до сторінки логіну (або інших публічних ресурсів) був явно дозволений доступ через permitAll().
  2. Помилка: забули додати @EnableWebSecurity. Без цієї анотації ваша конфігурація не застосується, а додаток просто не буде захищений.
  3. Помилка: використовуєте застарілий підхід WebSecurityConfigurerAdapter. З переходом на сучасний SecurityFilterChain багато прикладів в інтернеті можуть вводити в оману. Використовуйте новіші версії Spring Security, щоб уникнути проблем сумісності.

Практика: налаштування базової конфігурації

Додамо безпеку в наше навчальне додаток. Уявіть, що у нас є веб-додаток для керування книгами. Потрібно:

  1. Створити сторінку входу.
  2. Дозволити всім користувачам доступ до сторінок /login і /register.
  3. Захистити доступ до всіх інших сторінок.

Конфігурація:


@Configuration
@EnableWebSecurity
public class BookAppSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/login", "/register").permitAll() // Доступ для всіх
                .anyRequest().authenticated() // Все інше потребує аутентифікації
            .and()
            .formLogin() // Вмикаємо стандартну форму логіну
                .loginPage("/login") // Вказуємо кастомну сторінку логіну
                .permitAll()
            .and()
            .logout()
                .permitAll(); // Logout доступний всім
        return http.build();
    }
}

Тепер наш додаток безпечний: можна зареєструватися або увійти, але без авторизації доступ до інших сторінок закритий.


Посилання на документацію Spring Security, щоб поглибити знання.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ