Как настраивать аутентификацию и авторизацию в Spring Security?

Ответ

Spring Security настраивается для управления аутентификацией (кто вы) и авторизацией (что вам разрешено). Основные подходы — конфигурация через Java-код (рекомендуется) или XML.

Ключевые настройки:

  1. Аутентификация: Настройка источника данных пользователей (in-memory, JDBC, LDAP) и механизма (форма, OAuth2, JWT).
  2. Авторизация: Ограничение доступа к URL и методам на основе ролей и прав.
  3. Защита от атак: Включение защиты от CSRF и настройка CORS.
  4. Кастомизация: Создание собственных страниц входа, обработчиков ошибок и фильтров.

Пример базовой конфигурации (Java Config):

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
                .antMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
            .and()
            .logout()
                .permitAll()
            .and()
            .csrf().disable(); // Отключение CSRF для API (с осторожностью)
    }

    @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");
    }
}

Почему так? Конфигурация в коде типобезопасна и проще для рефакторинга. Расширение WebSecurityConfigurerAdapter (до Spring Security 5.7) или использование компонента SecurityFilterChain (новый стиль) позволяет централизованно управлять всей безопасностью приложения.

Ответ 18+ 🔞

О, блядь, смотри-ка, Spring Security! Ну это ж классика, ёпта, как "Муму" для программистов. Все её любят, а потом хотят утопить, потому что она нихуя не понятна с первого раза.

Вот представь, у тебя есть приложение — твой уютный дом, блядь. А Spring Security — это такой здоровый, немой Герасим, который стоит на пороге и говорит только «Му-му». То есть «не пущу». Или «пущу, но потом выебу». И тебе надо ему объяснить, кого пускать, куда пускать и как вообще с этим жить.

Основная идея, блядь, проще пареной репы:

  1. Аутентификация — это Герасим спрашивает: «Ты кто, сука? Пароль назови!». Проверяет, ты ли это, или какой-то левый пидорас.
  2. Авторизация — это когда ты уже внутрь прошёл, а Герасим тебя за рукав хватает: «А нахуй ты в спальню лезешь? Тебе туда нельзя, ты ж не админ! Иди на кухню, в раздел /public/холодильник». То есть проверяет права.

Как его настроить, этого Герасима? Есть два пути: через XML (это как объясняться с немым записками, старьё, блядь) и через Java-код. Java-код — это наш выбор, это типобезопасно и модно, как говно в пальто.

Смотри, вот тебе базовый пример, как сделать так, чтобы не всякий шкет мог к твоим эндпоинтам доступаться. Раньше надо было расширять WebSecurityConfigurerAdapter, это как старый дедовский способ.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN") // Сюда только царь-батюшка
                .antMatchers("/user/**").hasAnyRole("USER", "ADMIN") // Сюда свои люди
                .antMatchers("/public/**").permitAll() // А сюда вообще все, хоть собака зайди
                .anyRequest().authenticated() // На всё остальное — предъяви пропуск, блядь
            .and()
            .formLogin()
                .loginPage("/login")
                .permitAll() // На страницу логина пускаем всех, а то как зайти-то?
            .and()
            .logout()
                .permitAll() // Выйти тоже всем можно, свобода воли, нахуй
            .and()
            .csrf().disable(); // А это мы CSRF вырубаем, например, для API. ОСТОРОЖНО, БЛЯДЬ! Это как снять замок с двери. Только если знаешь, зачем.
    }

    @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"); // А вот этот — главный по тарелочкам
    }
}

Видишь эту хуйню {noop}? Это чтобы пароль не шифровался, а то Spring Security такой: «О, пароль! Сейчас я его захеширую!», а у нас в примере он открытый. {noop} — это как сказать: «Да похуй, оставь как есть, не еби мозг».

И самое главное, ёпта: эта конфигурация в коде — она как сценарий для Герасима. Ты ему чётко расписываешь: вот тут стой, тут проверяй, этих пускай, этих — нахуй. И он молча, но эффективно работает. А если что не так — он тебе просто «Му-му» в виде 403 Forbidden или 401 Unauthorized. Красота, блядь, в рот меня чих-пых!