Spring Security — действительно мощный инструмент, но чтобы начать использовать его в вашем проекте, нужно включить механизм безопасности. Аннотация @EnableWebSecurity, как можно догадаться из названия, для этого и служит.
В двух словах, @EnableWebSecurity:
- включает возможность использования Spring Security в вашем приложении.
- подключает конфигурации безопасности через класс
WebSecurityConfigurerAdapterили напрямую черезSecurityFilterChain. - инициализирует фильтры Spring Security для обработки всех входящих HTTP-запросов.
Без её добавления Spring Security будет существовать в вашем проекте как музейный экспонат — эстетично, но не слишком полезно. Давайте смотреть, как она работает и почему она так важна.
Что происходит после добавления @EnableWebSecurity?
Знаете, что происходит, когда вы добавляете @EnableWebSecurity в свой код? Spring Security просыпается и начинает охранять ваше приложение! Давайте заглянем под капот этой магии:
- Spring создает цепочку фильтров безопасности — своеобразный КПП для всех входящих запросов. Каждый запрос теперь проходит через эту охранную систему, прежде чем попасть в ваше приложение.
- Spring Security сразу же включает базовую защиту — как установка замков на все двери. По умолчанию все HTTP-ресурсы становятся закрытыми, и без правильных "ключей" (аутентификации) к ним не подобраться.
- И самое интересное — вы можете настроить эту систему безопасности под свои нужды! Хотите добавить собственные проверки? Используйте
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();
}
}
Давайте разберёмся, что делает этот код:
- Ограничение доступа по URL: методы
antMatchersпозволяют определять доступ на основе определённых URL. Например, все запросы к/publicразрешены без аутентификации. - Форма входа: мы кастомизировали стандартную форму входа, указав нашу страницу логина через метод
loginPage. Теперь вместо дефолтной страницы логина пользователи будут видеть ваш кастомный интерфейс. - Выход: мы позволяем любому пользователю выполнять 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();
}
}
Этот пример позволяет просматривать определённые публичные ресурсы (например, статику или главную страницу), но защищает всё остальное.
Частые ошибки и их устранение
- Ошибка: заблокированы все ресурсы, включая логин. Если вы настроите всё неправильно, то можете случайно заблокировать даже доступ к своей странице входа. Проверьте, чтобы к странице логина (или другим публичным ресурсам) был явно разрешён доступ через
permitAll(). - Ошибка: забыли добавить
@EnableWebSecurity. Без этой аннотации ваша конфигурация не применится, а приложение просто не будет защищено. - Ошибка: используете устаревший подход
WebSecurityConfigurerAdapter. С переходом на современныйSecurityFilterChainмногие примеры в интернете могут вводить вас в заблуждение. Используйте более новые версии Spring Security, чтобы избежать проблем с совместимостью.
Практика: настройка базовой конфигурации
Давайте добавим безопасность в наше учебное приложение. Представьте, что у нас есть веб-приложение для управления книгами. Нам нужно:
- Сделать страницу входа.
- Разрешить всем пользователям доступ к страницам
/loginи/register. - Защитить доступ ко всем другим страницам.
Конфигурация:
@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, чтобы углубить знания.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ