Gymterview
middle

Что такое Spring Security?

Spring Security – фреймворк для обеспечения безопасности Java-приложений, отвечающий за аутентификацию (кто ты?), авторизацию (что тебе разрешено?) и защиту от распространённых атак (CSRF, Session Fixation).

Что даёт «из коробки»

  • Все эндпоинты защищены (требуют аутентификации)
  • Форма логина /login
  • Защита от CSRF
  • Заголовки безопасности (X-Frame-Options, X-Content-Type-Options)

Базовая конфигурация (Spring Security 6+)

Пример SecurityConfig
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable()) // для REST API
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .requestMatchers("/api/users/**").hasAnyRole("USER", "ADMIN")
                .anyRequest().authenticated()
            )
            .httpBasic(Customizer.withDefaults());
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user = User.builder()
                .username("user")
                .password(passwordEncoder().encode("password"))
                .roles("USER").build();
        return new InMemoryUserDetailsManager(user);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

UserDetailsService для загрузки из БД

Пример
@Service
public class CustomUserDetailsService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        com.example.entity.User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("Не найден: " + username));
        return org.springframework.security.core.userdetails.User.builder()
                .username(user.getUsername())
                .password(user.getPassword())
                .roles(user.getRoles().stream().map(Role::getName).toArray(String[]::new))
                .build();
    }
}

На собеседовании: покажите понимание архитектуры (фильтры, UserDetailsService, PasswordEncoder). Частая ошибка – хранить пароли в открытом виде или забыть отключить CSRF для REST API без сессий (403 при POST).