Gymterview
middle

Что такое SecurityFilterChain и как он работает?

SecurityFilterChain – цепочка сервлетных фильтров, через которую проходит каждый HTTP-запрос в Spring Security. Каждый фильтр выполняет определённую задачу безопасности.

Порядок основных фильтров

Пример
HTTP запрос
     |
SecurityContextPersistenceFilter -- загрузка SecurityContext
     |
CsrfFilter -- проверка CSRF-токена
     |
LogoutFilter -- обработка logout
     |
UsernamePasswordAuthenticationFilter -- логин/пароль
     |
BasicAuthenticationFilter -- HTTP Basic
     |
BearerTokenAuthenticationFilter -- JWT/OAuth2
     |
ExceptionTranslationFilter -- обработка ошибок безопасности
     |
AuthorizationFilter -- проверка прав доступа
     |
Контроллер

Добавление собственного фильтра (JWT)

Пример
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .csrf(csrf -> csrf.disable())
        .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
        .authorizeHttpRequests(auth -> auth
            .requestMatchers(HttpMethod.POST, "/api/auth/**").permitAll()
            .anyRequest().authenticated()
        )
        .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
    return http.build();
}

Несколько SecurityFilterChain

Пример
@Bean @Order(1)
public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
    http.securityMatcher("/api/**") // для API -- JWT, без сессий
        .csrf(csrf -> csrf.disable())
        .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
        .authorizeHttpRequests(auth -> auth.anyRequest().authenticated());
    return http.build();
}

@Bean @Order(2)
public SecurityFilterChain webFilterChain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
        .formLogin(Customizer.withDefaults()); // для веб -- форма логина
    return http.build();
}

На собеседовании: покажите знание порядка фильтров и умение добавить свой. Частая ошибка – забыть filterChain.doFilter(request, response) в собственном фильтре (запрос «застрянет»). Также – неправильный @Order при нескольких SecurityFilterChain.