Java for Beginner
675 subscribers
560 photos
156 videos
12 files
858 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
6. @WithMockUser

Используется для создания фиктивного пользователя при тестировании.

Пример:

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithMockUser;

@SpringBootTest
public class MyServiceTest {

@Test
@WithMockUser(username = "testUser", roles = {"USER"})
public void testUserAccess() {
// Тестовый метод, где выполняется проверка с фиктивным пользователем
System.out.println("Тест с пользователем testUser");
}
}


Нюансы:
Используется только в тестах.
Можно указывать пользователя, роли и пароль для эмуляции различных ситуаций.


7. @EnableGlobalMethodSecurity

Эта аннотация включает поддержку аннотаций на уровне методов, таких как @PreAuthorize, @PostAuthorize, @Secured.

Пример:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class MethodSecurityConfig {
}


Нюансы:
Параметры:
prePostEnabled — включает
@PreAuthorize и @PostAuthorize.
securedEnabled — включает
@Secured.
jsr250Enabled — включает аннотации JSR-250 (
@RolesAllowed).

8. @RolesAllowed

Это аннотация стандарта JSR-250, которая ограничивает доступ к методам на основе ролей.

Пример:
import jakarta.annotation.security.RolesAllowed;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

@RolesAllowed("ROLE_USER")
public void userMethod() {
System.out.println("Метод для пользователей");
}
}


Нюансы:
Требует включения в конфигурации:
@EnableGlobalMethodSecurity(jsr250Enabled = true)


9. @CrossOrigin

Эта аннотация позволяет настройку CORS (Cross-Origin Resource Sharing).

Пример:
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ApiController {

@CrossOrigin(origins = "http://example.com")
@GetMapping("/data")
public String getData() {
return "Data from server";
}
}


Нюансы:
Применима для REST API для указания разрешенных доменов.

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

1. Основные Концепции

1.1 Аутентификация
Аутентификация — это процесс проверки подлинности пользователя. В Spring Security это обычно достигается с использованием имени пользователя и пароля, хотя возможны и другие подходы (JWT, OAuth2 и т.д.).

Основные компоненты аутентификации:
AuthenticationManager: Интерфейс, который определяет стратегию аутентификации.
AuthenticationProvider: Обрабатывает аутентификацию для конкретного типа данных (например, база данных, LDAP).
UserDetailsService: Загрузка пользователя по имени.
PasswordEncoder: Кодирует и проверяет пароли.


1.2 Авторизация
Авторизация — это процесс проверки, имеет ли пользователь право на выполнение определенных действий. В Spring Security это достигается с использованием ролей и разрешений.

Основные компоненты авторизации:
SecurityContextHolder: Хранит данные о текущем пользователе.
AccessDecisionManager: Принимает решение о доступе.
GrantedAuthority: Представляет роль или право.


2. Настройка Аутентификации и Авторизации

2.1 Добавление Зависимостей
Для начала необходимо добавить зависимости Spring Security в проект.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>


Gradle:
implementation 'org.springframework.boot:spring-boot-starter-security'


2.2 Настройка Конфигурации Безопасности

Создадим класс конфигурации, используя Java-based настройку:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable() // Отключение CSRF для упрощения
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll() // Доступ к публичным ресурсам
.requestMatchers("/admin/**").hasRole("ADMIN") // Доступ только для ADMIN
.anyRequest().authenticated() // Остальные запросы требуют аутентификации
)
.formLogin(form -> form
.loginPage("/login") // Кастомная страница логина
.permitAll()
)
.logout(logout -> logout
.permitAll()
);

return http.build();
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // Для кодирования паролей
}

// Пример встроенной аутентификации
@Bean
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user")
.password(passwordEncoder().encode("password"))
.roles("USER")
.and()
.withUser("admin")
.password(passwordEncoder().encode("admin"))
.roles("ADMIN");
}
}


#Java #Training #Spring #Security #Security_Authentication #Security_Authority
2.3 UserDetailsService и Пользовательская Аутентификация

Для работы с базой данных создадим собственную реализацию UserDetailsService.

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

@Service
public class CustomUserDetailsService implements UserDetailsService {

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// Заглушка для загрузки пользователя из базы данных
if ("admin".equals(username)) {
return User.builder()
.username("admin")
.password("$2a$10$7b4/uWVqOKu8.cQeMEjCE.Oz7w9f5qL4uLcyuKkKJ7TzPByHOfy92") // Зашифрованный пароль "password"
.roles("ADMIN")
.build();
} else {
throw new UsernameNotFoundException("Пользователь не найден");
}
}
}


3. Аутентификация REST API с JWT

3.1 Генерация JWT
Добавим сервис для генерации токенов JWT.
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Service;

import java.security.Key;
import java.util.Date;

@Service
public class JwtService {

private final String secretKey = "mysecretkeymysecretkeymysecretkeymysecretkey"; // 256 бит

public String generateToken(String username) {
Key key = Keys.hmacShaKeyFor(secretKey.getBytes());
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 1 день
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}
}


#Java #Training #Spring #Security #Security_Authentication #Security_Authority
3.2 Фильтрация JWT

Создадим фильтр для проверки JWT токенов.
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Key;
import java.util.Collections;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

private final String secretKey = "mysecretkeymysecretkeymysecretkeymysecretkey";

@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");

if (authHeader == null || !authHeader.startsWith("Bearer ")) {
filterChain.doFilter(request, response);
return;
}

String token = authHeader.substring(7);
try {
Key key = Keys.hmacShaKeyFor(secretKey.getBytes());
Claims claims = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody();

String username = claims.getSubject();
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(username, null, Collections.emptyList());
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (Exception e) {
e.printStackTrace();
}
filterChain.doFilter(request, response);
}
}


4. Авторизация на Уровне Методов

Spring Security позволяет ограничивать доступ к методам с помощью аннотаций.

Пример с @PreAuthorize:
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;

@Service
public class ReportService {

@PreAuthorize("hasRole('ADMIN')")
public void generateAdminReport() {
System.out.println("Отчет для администратора");
}

@PreAuthorize("hasRole('USER')")
public void generateUserReport() {
System.out.println("Отчет для пользователя");
}
}


Для активации аннотаций на уровне методов, необходимо включить их в конфигурации:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig {
}


#Java #Training #Spring #Security #Security_Authentication #Security_Authority
Проверка подлинности пользователя в Spring Security

Spring Security предлагает различные подходы для аутентификации пользователей. Каждый из них предназначен для конкретных случаев использования, начиная от классической формы логина до современных методов на основе токенов, таких как JWT и OAuth2.

1. Форма логина (Form-Based Authentication)


1.1 Описание
Форма логина — это один из самых популярных методов аутентификации для веб-приложений. Пользователь вводит имя пользователя и пароль на странице входа, которые отправляются на сервер для проверки.

1.2 Настройка
Шаги настройки:
Настройка страницы логина.
Конфигурация Spring
Security для обработки формы.

Пример конфигурации:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated() // Все запросы требуют аутентификации
)
.formLogin(form -> form
.loginPage("/login") // Кастомная страница логина
.permitAll() // Разрешить доступ к странице логина
)
.logout(logout -> logout
.permitAll() // Разрешить выход
);

return http.build();
}
}


Шаблон страницы логина:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login</title>
</head>
<body>
<h2>Login</h2>
<form th:action="@{/login}" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username" /><br>
<label for="password">Password:</label>
<input type="password" id="password" name="password" /><br>
<button type="submit">Login</button>
</form>
</body>
</html>


Нюансы:
По умолчанию Spring Security предоставляет стандартную страницу логина, если не указана кастомная.
Все данные передаются через HTTPS для обеспечения безопасности.


2. HTTP Basic Authentication

2.1 Описание
HTTP Basic Authentication — это простой метод аутентификации, при котором имя пользователя и пароль передаются в заголовке HTTP-запроса.

2.2 Настройка
Пример конфигурации:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.httpBasic(); // Включение HTTP Basic
return http.build();
}


Пример запроса:
GET /api/resource HTTP/1.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=


Нюансы:
Подходит для API, но не рекомендуется для публичных веб-приложений, так как чувствительные данные передаются в заголовках.
Необходимо использовать HTTPS для защиты данных.


3. Token-Based Authentication


3.1 Описание
Вместо хранения сессий на сервере, токены используются для аутентификации. Самый популярный вариант — JWT (JSON Web Token).

3.2 Настройка JWT Authentication
1. Генерация токена:
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

import java.security.Key;
import java.util.Date;

@Service
public class JwtService {
private final String secretKey = "mysecretkeymysecretkeymysecretkeymysecretkey"; // 256 бит
private final long expirationMs = 86400000; // 1 день

public String generateToken(String username) {
Key key = Keys.hmacShaKeyFor(secretKey.getBytes());
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + expirationMs))
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}
}


#Java #Training #Spring #Security #Security_Authority
2. JWT фильтр для валидации токенов:
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Key;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

private final String secretKey = "mysecretkeymysecretkeymysecretkeymysecretkey";

@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer ")) {
String token = authHeader.substring(7);
Key key = Keys.hmacShaKeyFor(secretKey.getBytes());
String username = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody()
.getSubject();

if (username != null) {
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(username, null, null));
}
}
filterChain.doFilter(request, response);
}
}


3. Регистрация фильтра:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}


Нюансы:
JWT-токены не требуют хранения на сервере.
Важно правильно настроить срок действия токена и защиту от кражи.


#Java #Training #Spring #Security #Security_Authority
4. OAuth2 Authentication

4.1 Описание
OAuth2 — это стандарт аутентификации, который позволяет пользователям аутентифицироваться с помощью сторонних сервисов, таких как Google, Facebook и т.д.

4.2 Настройка
Spring Security поддерживает OAuth2 через spring-boot-starter-oauth2-client.

Добавление зависимости:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>


Пример конфигурации:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.oauth2Login(oauth -> oauth
.loginPage("/oauth2/authorization/google") // Настройка страницы логина
);
return http.build();
}
}


Нюансы:
OAuth2 требует настройки клиентских данных (client ID и secret).
Поддерживается автоматический редирект на стороннюю страницу аутентификации.


5. LDAP Authentication

5.1 Описание
LDAP используется для аутентификации через службы каталогов, такие как Active Directory.

Пример конфигурации:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.formLogin()
.and()
.ldapAuthentication()
.userDnPatterns("uid={0},ou=people")
.groupSearchBase("ou=groups")
.contextSource()
.url("ldap://localhost:8389/dc=springframework,dc=org");
return http.build();
}


Нюансы:
Требуется настроить LDAP сервер.
Используется в корпоративных приложениях.


Spring Security поддерживает множество способов аутентификации, начиная от традиционных форм логина и заканчивая современными подходами, такими как OAuth2 и JWT. Выбор подхода зависит от требований приложения:
Для веб-приложений подойдет форма логина.
Для REST API — JWT.
Для корпоративных систем — LDAP.



#Java #Training #Spring #Security #Security_Authority
Использование базы данных для хранения пользователей в Spring Security

Хранение пользователей в базе данных является наиболее распространённым способом управления аутентификацией в реальных приложениях. Это позволяет централизовать информацию о пользователях и их ролях, упрощая управление и обеспечивая безопасность.

1. Общая архитектура

Когда Spring Security использует базу данных для аутентификации, основные элементы выглядят следующим образом:
База данных: Хранит таблицы пользователей и ролей.
UserDetailsService: Загрузчик пользователей, который извлекает данные из базы данных.
PasswordEncoder: Обеспечивает хэширование паролей.
AuthenticationManager: Выполняет процесс аутентификации.
Роли и привилегии: Хранятся в базе для управления авторизацией.


2. Шаги по реализации

2.1 Настройка базы данных
Создайте базу данных и добавьте необходимые таблицы для хранения пользователей и их ролей. Рассмотрим пример на основе реляционной базы данных.

Пример SQL-схемы:
-- Таблица пользователей
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
enabled BOOLEAN NOT NULL
);

-- Таблица ролей
CREATE TABLE roles (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE
);

-- Таблица связи пользователей и ролей
CREATE TABLE user_roles (
user_id BIGINT NOT NULL,
role_id BIGINT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (role_id) REFERENCES roles(id)
);


Пример данных:
INSERT INTO users (username, password, enabled) VALUES 
('admin', '$2a$10$7a6yXl4bKh7QvXuUIhEY2eP2d6P5M6NmrkObWbxODeEM.gSUTZlVu', true), -- пароль: admin
('user', '$2a$10$w8y4/gM3/uF9Rf/5S1OejX.6M4KZt7eEPY2OnB9oRxCSU8Y4.jK8u', true); -- пароль: user

INSERT INTO roles (name) VALUES ('ROLE_ADMIN'), ('ROLE_USER');

INSERT INTO user_roles (user_id, role_id) VALUES
(1, 1), -- admin имеет роль ROLE_ADMIN
(2, 2); -- user имеет роль ROLE_USER
Пароли были закодированы с использованием BCryptPasswordEncoder.


2.2 Настройка приложения
Подключение к базе данных

Настройте подключение к базе данных в файле application.properties (или application.yml):

application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/spring_security_db
spring.datasource.username=root
spring.datasource.password=yourpassword
spring.jpa.hibernate.ddl-auto=update


Зависимости
Добавьте зависимости для работы с базой данных и Spring Security:

Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>


Gradle:
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'mysql:mysql-connector-java'


#Java #Training #Spring #Security #Security_BD
2.3 Реализация UserDetailsService
Spring Security использует интерфейс UserDetailsService для загрузки пользователей из базы данных. Реализуем его в нашем приложении.
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Collections;

@Service
public class CustomUserDetailsService implements UserDetailsService {

private final UserRepository userRepository;

public CustomUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserEntity userEntity = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("Пользователь не найден: " + username));

return User.builder()
.username(userEntity.getUsername())
.password(userEntity.getPassword())
.authorities(userEntity.getRoles().stream()
.map(role -> "ROLE_" + role.getName())
.toList())
.accountExpired(false)
.accountLocked(false)
.credentialsExpired(false)
.disabled(!userEntity.isEnabled())
.build();
}
}


2.4 Создание Репозиториев
Создадим репозитории для работы с таблицами пользователей и ролей.


UserRepository:
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UserRepository extends JpaRepository<UserEntity, Long> {
Optional<UserEntity> findByUsername(String username);
}


RoleRepository:
import org.springframework.data.jpa.repository.JpaRepository;

public interface RoleRepository extends JpaRepository<RoleEntity, Long> {
}


2.5 Создание Сущностей
UserEntity:
import jakarta.persistence.*;
import java.util.Set;

@Entity
@Table(name = "users")
public class UserEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false, unique = true)
private String username;

@Column(nullable = false)
private String password;

@Column(nullable = false)
private boolean enabled;

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "user_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<RoleEntity> roles;

// Геттеры и сеттеры
}


RoleEntity:
import jakarta.persistence.*;
import java.util.Set;

@Entity
@Table(name = "roles")
public class RoleEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false, unique = true)
private String name;

@ManyToMany(mappedBy = "roles")
private Set<UserEntity> users;

// Геттеры и сеттеры
}


#Java #Training #Spring #Security #Security_BD
2.6 Настройка Конфигурации Безопасности
Настроим SecurityConfig для использования пользовательской реализации UserDetailsService.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

private final CustomUserDetailsService customUserDetailsService;

public SecurityConfig(CustomUserDetailsService customUserDetailsService) {
this.customUserDetailsService = customUserDetailsService;
}

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin()
.and()
.logout().permitAll();

return http.build();
}

@Bean
public AuthenticationManager authManager(HttpSecurity http, PasswordEncoder passwordEncoder)
throws Exception {
return http.getSharedObject(AuthenticationManagerBuilder.class)
.userDetailsService(customUserDetailsService)
.passwordEncoder(passwordEncoder)
.and()
.build();
}

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


3. Тестирование

Теперь, когда настройка завершена:
Вы можете зарегистрировать новых пользователей, хэшировать их пароли с помощью BCryptPasswordEncoder и сохранять их в базу данных.
При попытке входа Spring
Security будет извлекать пользователя из базы данных через CustomUserDetailsService.

#Java #Training #Spring #Security #Security_BD