Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методички / spring_lab5.pdf
Скачиваний:
0
Добавлен:
28.06.2026
Размер:
208.26 Кб
Скачать

import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service;

@Service

@RequiredArgsConstructor

public class CustomUserDetailsService implements UserDetailsService {

private final UserRepository userRepository;

@Override

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

User user = userRepository.findByEmail(username)

.orElseThrow(() -> new UsernameNotFoundException("Пользователь не найден"));

return new CustomUserDetails(user);

}

}

Что здесь происходит:

• Spring Security передает в метод loadUserByUsername() логин пользователя;

мы ищем пользователя в базе данных по email ;

если пользователь найден, создаем объект CustomUserDetails ;

если пользователь не найден, выбрасываем UsernameNotFoundException .

Важно: UserDetailsService не проверяет пароль самостоятельно. Его задача — только загрузить пользователя по логину. Сравнение пароля выполняет DaoAuthenticationProvider

через PasswordEncoder . Именно поэтому UserDetailsService считается read-only DAO-

слоем для механизма аутентификации. (docs.spring.io)

3.4. Почему это удобнее, чем возвращать встроенный User

Можно было бы вернуть объект org.springframework.security.core.userdetails.User прямо из CustomUserDetailsService , но отдельный класс CustomUserDetails дает несколько преимуществ:

проще расширять логику в будущем;

можно сохранить доступ к исходной сущности User ;

код становится ближе к реальным проектам, где часто нужны дополнительные поля пользователя;

лучше видно границу между сущностью базы данных и адаптером безопасности.

Часть 4. Шифрование паролей и конфигурация безопасности

Пароли нельзя хранить в открытом виде. При регистрации пароль должен шифроваться, а при логине — сравниваться через тот же механизм шифрования.

8

4.1. Создайте конфигурационный класс SecurityConfig

package org.example.config;

import lombok.RequiredArgsConstructor;

import org.example.security.CustomUserDetailsService; import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import

org.springframework.security.config.annotation.authentication.configuration.AuthenticationConf import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import

org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain;

@Configuration

@EnableMethodSecurity

@RequiredArgsConstructor public class SecurityConfig {

private final CustomUserDetailsService customUserDetailsService;

@Bean

public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder();

}

@Bean

public DaoAuthenticationProvider authenticationProvider() { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(customUserDetailsService); provider.setPasswordEncoder(passwordEncoder());

return provider;

}

@Bean

public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {

return configuration.getAuthenticationManager();

}

@Bean

public SecurityFilterChain securityFilterChain(HttpSecurity http) throws

9

Соседние файлы в папке Методички