Все самое полезное для Java-разработчика в одном канале.
Учиться у нас: clc.to/AATM8w
Для обратной связи: @proglibrary_feeedback_bot
По рекламе: @tproger_sales_bot
РКН: https://gosuslugi.ru/snet/67a5bbda1b17b35b6c1a55c4
Post #7557
2.31K
🔧 Spring Security 6: конфигурация без устаревших паттернов
WebSecurityConfigurerAdapter удалён в Spring Security 6. Новый подход — компонентная модель через SecurityFilterChain. Разбираем актуальную конфигурацию.
🔹 Решение
▪️ Базовая конфигурация
▪️ Несколько SecurityFilterChain для разных путей
▪️ Method-level security
Несколько SecurityFilterChain с @Order — правильный способ применять разные политики безопасности к разным частям приложения. securityMatcher определяет к каким путям применяется цепочка. Первая совпавшая цепочка побеждает.
⚠️ hasIpAddress для actuator в production — минимум. Идеально вынести actuator на отдельный порт (management.server.port=8081) и закрыть его на уровне сети.
══════ Навигация ══════
Вакансии • Задачи • Собесы
🐸 Библиотека джависта
#Enterprise
WebSecurityConfigurerAdapter удалён в Spring Security 6. Новый подход — компонентная модель через SecurityFilterChain. Разбираем актуальную конфигурацию.
🔹 Решение
▪️ Базовая конфигурация
@Configuration
@EnableWebSecurity
@EnableMethodSecurity // включает @PreAuthorize, @PostAuthorize
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringRequestMatchers("/api/webhooks/**"))
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health").permitAll()
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated())
.oauth2ResourceServer(oauth2 -> oauth2
.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtConverter())))
.exceptionHandling(ex -> ex
.authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
.accessDeniedHandler(new BearerTokenAccessDeniedHandler()))
.build();
}
@Bean
public JwtAuthenticationConverter jwtConverter() {
JwtGrantedAuthoritiesConverter converter = new JwtGrantedAuthoritiesConverter();
converter.setAuthoritiesClaimName("roles");
converter.setAuthorityPrefix("ROLE_");
JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter();
jwtConverter.setJwtGrantedAuthoritiesConverter(converter);
return jwtConverter;
}
}
▪️ Несколько SecurityFilterChain для разных путей
@Bean
@Order(1)
public SecurityFilterChain actuatorChain(HttpSecurity http) throws Exception {
return http
.securityMatcher("/actuator/**")
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health").permitAll()
.anyRequest().hasIpAddress("10.0.0.0/8"))
.build();
}
@Bean
@Order(2)
public SecurityFilterChain apiChain(HttpSecurity http) throws Exception {
return http
.securityMatcher("/api/**")
.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
.build();
}
▪️ Method-level security
@Service
public class OrderService {
@PreAuthorize("hasRole('ADMIN') or #userId == authentication.name")
public List<Order> getOrders(String userId) { ... }
@PostAuthorize("returnObject.userId == authentication.name")
public Order getOrder(Long orderId) { ... }
}
Несколько SecurityFilterChain с @Order — правильный способ применять разные политики безопасности к разным частям приложения. securityMatcher определяет к каким путям применяется цепочка. Первая совпавшая цепочка побеждает.
⚠️ hasIpAddress для actuator в production — минимум. Идеально вынести actuator на отдельный порт (management.server.port=8081) и закрыть его на уровне сети.
══════ Навигация ══════
Вакансии • Задачи • Собесы
🐸 Библиотека джависта
#Enterprise
- 👍 8
- ❤ 3
- 🔥 2






