Ответ
Кастомизация в Spring Security обычно реализуется через расширение ключевых компонентов.
1. Кастомная аутентификация (например, по JWT):
- Создайте фильтр для извлечения и валидации токена.
- Реализуйте
AuthenticationProviderили используйте стандартный, установив кастомныйUserDetailsService.
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) {
// Ваша логика загрузки пользователя из БД или другого источника
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
// Преобразование ролей/прав в GrantedAuthority
List<GrantedAuthority> authorities = user.getRoles().stream()
.map(role -> new SimpleGrantedAuthority("ROLE_" + role.getName()))
.collect(Collectors.toList());
return new org.springframework.security.core.userdetails.User(
user.getUsername(),
user.getPassword(),
authorities
);
}
}
2. Кастомная конфигурация доступа: Настройте SecurityFilterChain, чтобы определить правила для разных эндпоинтов и подключить свои фильтры.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authz -> authz
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers("/api/user/**").hasAnyRole("USER", "ADMIN")
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
// Добавление кастомного JWT-фильтра перед стандартным
.addFilterBefore(new JwtAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class)
.csrf(csrf -> csrf.disable()) // Отключаем для stateless API
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
return http.build();
}
3. Кастомная логика авторизации: Для сложных правил (например, на основе атрибутов объекта) реализуйте @PreAuthorize с SpEL или создайте собственный PermissionEvaluator.