webprogr.ru Новости

RSS

{{toodo.preview}}

...
{{toodo.name}}

{{toodo.preview}}

далее..

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

смотреть..

toodo.name

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

перейти...

{{toodo.preview}}

...
{{toodo.name}}

{{toodo.preview}}

далее..

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

смотреть..

toodo.name

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

перейти...


Последние новости

Аутентификация и авторизация в Spring Security

Аутентификация и авторизация в Spring Security

    Аутентификация — процесс проверки личности пользователя (кто он).
    Авторизация — проверка прав доступа (что он может делать).

    В Spring Security аутентификация строится на основе
    интерфейсов UserDetails, UserDetailsService и AuthenticationProvider.

    Основные этапы:

        Пользователь вводит логин и пароль.

        SecurityFilterChain передает запрос в AuthenticationProvider.

        Провайдер сверяет данные с базой и создает объект Authentication.

        Информация сохраняется в SecurityContext.

        При последующих запросах права проверяются автоматически.

Подробное объяснение

Чтобы понять, как Spring Security обрабатывает пользователей, важно разделить два понятия:
— аутентификация отвечает на вопрос «кто этот человек?»,
— авторизация — «имеет ли он право выполнить это действие?».
1. Ключевые интерфейсы
UserDetails

Описывает пользователя: имя, пароль и роли.

public class MyUserDetails implements UserDetails {
    private final User user;

    public MyUserDetails(User user) { this.user = user; }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return List.of(new SimpleGrantedAuthority("ROLE_" + user.getRole()));
    }

    @Override
    public String getPassword() { return user.getPassword(); }

    @Override
    public String getUsername() { return user.getUsername(); }

    @Override
    public boolean isAccountNonExpired() { return true; }

    @Override
    public boolean isAccountNonLocked() { return true; }

    @Override
    public boolean isCredentialsNonExpired() { return true; }

    @Override
    public boolean isEnabled() { return true; }
}

Spring Security всегда оперирует объектами UserDetails, даже если вы храните пользователей в собственной таблице.
UserDetailsService

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

@Service
public class MyUserDetailsService implements UserDetailsService {

    private final UserRepository repository;

    public MyUserDetailsService(UserRepository repository) {
        this.repository = repository;
    }

    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
        return repository.findByUsername(username)
                .map(MyUserDetails::new)
                .orElseThrow(() ->
                        new UsernameNotFoundException("Пользователь не найден"));
    }
}

Когда пользователь пытается войти, Spring вызывает этот сервис, получает UserDetails и сравнивает пароль с введенным.
2. Настройка аутентификации

В конфигурации Spring Security нужно указать, как система будет проверять пользователей.

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/login", "/register").permitAll()
                .anyRequest().authenticated())
            .formLogin(Customizer.withDefaults())
            .build();
    }

    @Bean
    public UserDetailsService userDetailsService(UserRepository repository) {
        return new MyUserDetailsService(repository);
    }

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

Обратите внимание:

    formLogin() включает стандартную страницу входа;

    PasswordEncoder обязателен — Spring не позволит хранить пароль в открытом виде;

    BCryptPasswordEncoder — безопасный алгоритм хеширования паролей, рекомендуемый по умолчанию.

3. Создание пользователя в памяти (для теста)

Для учебных примеров можно не подключать базу, а создать пользователя прямо в конфигурации:

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

Теперь можно войти в приложение с логином admin и паролем 1234.
4. Авторизация по ролям и аннотации

После успешной аутентификации система знает, какие роли у пользователя.
Для ограничения доступа к методам используются аннотации:

@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(Long id) { ... }

@PreAuthorize("hasAnyRole('MANAGER', 'ADMIN')")
public void viewReport() { ... }

Spring проверит роли перед выполнением метода и вернет 403 Forbidden,
если у пользователя нет соответствующих прав.

Чтобы эти аннотации работали, нужно включить их в конфигурации:

@EnableMethodSecurity
public class SecurityConfig { ... }

5. Хранение состояния пользователя

После успешного входа информация о пользователе хранится в SecurityContext.
Этот контекст доступен в любом месте программы:

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();
System.out.println("Текущий пользователь: " + username);

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

Итог:

Аутентификация и авторизация в Spring Security разделены, но работают вместе.
UserDetailsService отвечает за загрузку данных пользователя,
AuthenticationManager и PasswordEncoder — за проверку подлинности,
а аннотации @PreAuthorize и @Secured обеспечивают контроль доступа на уровне методов.
Рейтинг@Mail.ru