Аутентификация и Авторизация в 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 в проект.
Gradle:
2.2 Настройка Конфигурации Безопасности
Создадим класс конфигурации, используя Java-based настройку:
#Java #Training #Spring #Security #Security_Authentication #Security_Authority
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.
3. Аутентификация REST API с JWT
3.1 Генерация JWT
Добавим сервис для генерации токенов JWT.
#Java #Training #Spring #Security #Security_Authentication #Security_Authority
Для работы с базой данных создадим собственную реализацию 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 токенов.
4. Авторизация на Уровне Методов
Spring Security позволяет ограничивать доступ к методам с помощью аннотаций.
Пример с @PreAuthorize:
Для активации аннотаций на уровне методов, необходимо включить их в конфигурации:
#Java #Training #Spring #Security #Security_Authentication #Security_Authority
Создадим фильтр для проверки 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
Что выведет код?
#Tasks
class Parent1212 {
int value = 10;
void display() {
System.out.println("Parent display");
}
}
class Child1212 extends Parent1212 {
int value = 20;
@Override
void display() {
System.out.println("Child display");
}
void showValues() {
System.out.println("Child value: " + value);
System.out.println("Parent value: " + super.value);
}
}
public class Task121224_1 {
public static void main(String[] args) {
Parent1212 obj1 = new Child1212();
obj1.display();
Child1212 obj2 = new Child1212();
obj2.showValues();
}
}
#Tasks
Проверка подлинности пользователя в Spring Security
Spring Security предлагает различные подходы для аутентификации пользователей. Каждый из них предназначен для конкретных случаев использования, начиная от классической формы логина до современных методов на основе токенов, таких как JWT и OAuth2.
1. Форма логина (Form-Based Authentication)
1.1 Описание
Форма логина — это один из самых популярных методов аутентификации для веб-приложений. Пользователь вводит имя пользователя и пароль на странице входа, которые отправляются на сервер для проверки.
1.2 Настройка
Шаги настройки:
Настройка страницы логина.
Конфигурация Spring Security для обработки формы.
Пример конфигурации:
Шаблон страницы логина:
Нюансы:
По умолчанию Spring Security предоставляет стандартную страницу логина, если не указана кастомная.
Все данные передаются через HTTPS для обеспечения безопасности.
2. HTTP Basic Authentication
2.1 Описание
HTTP Basic Authentication — это простой метод аутентификации, при котором имя пользователя и пароль передаются в заголовке HTTP-запроса.
2.2 Настройка
Пример конфигурации:
Пример запроса:
Нюансы:
Подходит для API, но не рекомендуется для публичных веб-приложений, так как чувствительные данные передаются в заголовках.
Необходимо использовать HTTPS для защиты данных.
3. Token-Based Authentication
3.1 Описание
Вместо хранения сессий на сервере, токены используются для аутентификации. Самый популярный вариант — JWT (JSON Web Token).
3.2 Настройка JWT Authentication
1. Генерация токена:
#Java #Training #Spring #Security #Security_Authority
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 фильтр для валидации токенов:
3. Регистрация фильтра:
Нюансы:
JWT-токены не требуют хранения на сервере.
Важно правильно настроить срок действия токена и защиту от кражи.
#Java #Training #Spring #Security #Security_Authority
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.
Добавление зависимости:
Пример конфигурации:
Нюансы:
OAuth2 требует настройки клиентских данных (client ID и secret).
Поддерживается автоматический редирект на стороннюю страницу аутентификации.
5. LDAP Authentication
5.1 Описание
LDAP используется для аутентификации через службы каталогов, такие как Active Directory.
Пример конфигурации:
Нюансы:
Требуется настроить LDAP сервер.
Используется в корпоративных приложениях.
Spring Security поддерживает множество способов аутентификации, начиная от традиционных форм логина и заканчивая современными подходами, такими как OAuth2 и JWT. Выбор подхода зависит от требований приложения:
Для веб-приложений подойдет форма логина.
Для REST API — JWT.
Для корпоративных систем — LDAP.
#Java #Training #Spring #Security #Security_Authority
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-схемы:
Пример данных:
2.2 Настройка приложения
Подключение к базе данных
Настройте подключение к базе данных в файле application.properties (или application.yml):
application.properties:
Зависимости
Добавьте зависимости для работы с базой данных и Spring Security:
Maven:
Gradle:
#Java #Training #Spring #Security #Security_BD
Хранение пользователей в базе данных является наиболее распространённым способом управления аутентификацией в реальных приложениях. Это позволяет централизовать информацию о пользователях и их ролях, упрощая управление и обеспечивая безопасность.
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 для загрузки пользователей из базы данных. Реализуем его в нашем приложении.
2.4 Создание Репозиториев
Создадим репозитории для работы с таблицами пользователей и ролей.
UserRepository:
RoleRepository:
2.5 Создание Сущностей
UserEntity:
RoleEntity:
#Java #Training #Spring #Security #Security_BD
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.
3. Тестирование
Теперь, когда настройка завершена:
Вы можете зарегистрировать новых пользователей, хэшировать их пароли с помощью BCryptPasswordEncoder и сохранять их в базу данных.
При попытке входа Spring Security будет извлекать пользователя из базы данных через CustomUserDetailsService.
#Java #Training #Spring #Security #Security_BD
Настроим 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
Что выведет код?
#Tasks
class Parent1312 {
String name = "Parent";
void printName() {
System.out.println("Name: " + name);
}
}
class Child1312 extends Parent1312 {
String name = "Child";
@Override
void printName() {
System.out.println("Name: " + name);
}
}
public class Task131224_1 {
public static void main(String[] args) {
Parent1312 obj1 = new Child1312();
Child1312 obj2 = new Child1312();
System.out.println("Direct access:");
System.out.println("obj1.name: " + obj1.name);
System.out.println("obj2.name: " + obj2.name);
System.out.println("Method call:");
obj1.printName();
obj2.printName();
}
}
#Tasks
И еще немного про команды в JVM
1. Основные специальные символы
1.1. Символ * (звёздочка)
Используется для подстановки любого количества символов.
Применяется для работы с несколькими файлами.
1.2. Символ ?
Подставляет любой один символ.
1.3. Символы > и >>
>: перенаправляет вывод в файл, заменяя его содержимое.
>>: перенаправляет вывод в файл, добавляя данные в конец.
1.4. Символ <
Перенаправляет ввод из файла.
1.5. Символы | и &&
|: перенаправляет вывод одной команды на вход другой.
&&: выполняет следующую команду только если предыдущая завершилась успешно.
1.6. Символ &
Запускает процесс в фоновом режиме.
1.7. Кавычки (", ', `)
Кавычки используются для обработки пробелов, спецсимволов и выполнения команд внутри строки.
Двойные кавычки ("): сохраняют пробелы, но позволяют интерполяцию переменных.
Одинарные кавычки ('): игнорируют интерполяцию переменных и спецсимволов.
Обратные кавычки (`): выполняют команду и подставляют её вывод.
1.8. Символы []
Указывают диапазоны символов для подстановки.
2. Пример комбинирования специальных символов
Этот пример:
Компилирует все файлы .java в указанной директории.
Если компиляция успешна, запускает класс Main.
Записывает вывод программы в файл output.log.
3. Особенности в разных ОС
Windows (CMD):
Некоторые символы требуют экранирования с помощью ^:
В PowerShell используется обратный апостроф (`) для экранирования:
Linux и MacOS (Bash, Zsh):
Используются стандартные символы, такие как \ для экранирования.
4. Полезные советы
Если необходимо передать символы буквально (например, *, ?, или $), экранируйте их с помощью \:
Используйте кавычки для обработки путей с пробелами:
#Java #Training #Medium #JVM_Commands
1. Основные специальные символы
1.1. Символ * (звёздочка)
Используется для подстановки любого количества символов.
Применяется для работы с несколькими файлами.
javac src/com/example/*.java
Этот пример компилирует все файлы .java в указанной директории.
1.2. Символ ?
Подставляет любой один символ.
javac src/com/example/Fi?e.java
Компилирует файлы, чьи имена начинаются с Fi, заканчиваются на e и содержат один символ между ними (например, File.java, Fike.java).
1.3. Символы > и >>
>: перенаправляет вывод в файл, заменяя его содержимое.
>>: перенаправляет вывод в файл, добавляя данные в конец.
java -Xlog:gc > gc.log
Записывает логи сборщика мусора в файл gc.log, перезаписывая его содержимое.
java -Xlog:gc >> gc.log
Добавляет новые логи в конец файла gc.log.
1.4. Символ <
Перенаправляет ввод из файла.
java com.example.MyClass < input.txt
Передаёт содержимое файла input.txt как стандартный ввод для программы.
1.5. Символы | и &&
|: перенаправляет вывод одной команды на вход другой.
&&: выполняет следующую команду только если предыдущая завершилась успешно.
java com.example.MyClass | grep "Error"
Передаёт вывод программы в команду grep, которая фильтрует строки, содержащие Error.
javac MyClass.java && java MyClass
Компилирует MyClass.java и, если компиляция прошла успешно, запускает программу.
1.6. Символ &
Запускает процесс в фоновом режиме.
java com.example.MyClass &
Запускает программу в фоновом режиме, позволяя продолжать вводить команды.
1.7. Кавычки (", ', `)
Кавычки используются для обработки пробелов, спецсимволов и выполнения команд внутри строки.
Двойные кавычки ("): сохраняют пробелы, но позволяют интерполяцию переменных.
java -Dpath="C:\My Folder"
Одинарные кавычки ('): игнорируют интерполяцию переменных и спецсимволов.
java -Dpath='C:\My Folder'
Обратные кавычки (`): выполняют команду и подставляют её вывод.
java -Dtime=`date`
1.8. Символы []
Указывают диапазоны символов для подстановки.
javac src/[a-c]*.java
Компилирует все файлы, начинающиеся с букв a, b или c.
2. Пример комбинирования специальных символов
javac src/com/example/*.java && java -cp src com.example.Main > output.log
Этот пример:
Компилирует все файлы .java в указанной директории.
Если компиляция успешна, запускает класс Main.
Записывает вывод программы в файл output.log.
3. Особенности в разных ОС
Windows (CMD):
Некоторые символы требуют экранирования с помощью ^:
java -Dpath="C:\My^ Folder"
В PowerShell используется обратный апостроф (`) для экранирования:
java -Dpath="C:\My` Folder"
Linux и MacOS (Bash, Zsh):
Используются стандартные символы, такие как \ для экранирования.
java -Dpath="C:\My\ Folder"
4. Полезные советы
Если необходимо передать символы буквально (например, *, ?, или $), экранируйте их с помощью \:
java -Dspecial=\* com.example.Main
Используйте кавычки для обработки путей с пробелами:
javac -cp "lib/some library.jar" MyClass.java
#Java #Training #Medium #JVM_Commands
Настройка ролей и прав доступа в Spring Security
1. Основные концепции
Authentication (аутентификация): процесс проверки подлинности пользователя, т.е. кто он такой.
Authorization (авторизация): процесс проверки прав пользователя, т.е. что он может делать.
Principal: представляет текущего аутентифицированного пользователя.
GrantedAuthority: представляет разрешение или роль, назначенную пользователю.
Role: определенная категория, которая группирует определенные разрешения.
2. Архитектура и основные компоненты
SecurityContext и SecurityContextHolder: SecurityContext хранит данные о текущей аутентификации, включая Principal и GrantedAuthority. SecurityContextHolder — это контейнер, который обеспечивает доступ к текущему SecurityContext.
AuthenticationManager: основной интерфейс для выполнения аутентификации. Он принимает объект Authentication и возвращает аутентифицированный объект или выбрасывает исключение.
AccessDecisionManager: принимает решение о предоставлении или отклонении доступа к защищенному ресурсу на основе предоставленных прав.
FilterSecurityInterceptor: фильтр, который проверяет доступ к ресурсам на основе настроек безопасности.
3. Настройка ролей и прав доступа
Spring Security поддерживает настройку через Java-код (Java Config) и XML.
3.1 Подключение Spring Security
Добавьте зависимости в pom.xml:
3.2 Создание конфигурационного класса
Конфигурация Spring Security осуществляется с помощью аннотации @EnableWebSecurity и наследования от класса WebSecurityConfigurerAdapter.
Пример базовой конфигурации:
4. Роли и права: тонкая настройка
Роли (ROLE_*) — это абстракция для группировки прав. Spring Security требует, чтобы роли начинались с префикса ROLE_.
4.1 Настройка прав доступа через аннотации
Spring Security поддерживает аннотации для определения прав доступа на уровне методов.
Включение поддержки аннотаций:
В классе конфигурации добавьте @EnableGlobalMethodSecurity:
#Java #Training #Spring #Security #Security_Roles
1. Основные концепции
Authentication (аутентификация): процесс проверки подлинности пользователя, т.е. кто он такой.
Authorization (авторизация): процесс проверки прав пользователя, т.е. что он может делать.
Principal: представляет текущего аутентифицированного пользователя.
GrantedAuthority: представляет разрешение или роль, назначенную пользователю.
Role: определенная категория, которая группирует определенные разрешения.
2. Архитектура и основные компоненты
SecurityContext и SecurityContextHolder: SecurityContext хранит данные о текущей аутентификации, включая Principal и GrantedAuthority. SecurityContextHolder — это контейнер, который обеспечивает доступ к текущему SecurityContext.
AuthenticationManager: основной интерфейс для выполнения аутентификации. Он принимает объект Authentication и возвращает аутентифицированный объект или выбрасывает исключение.
AccessDecisionManager: принимает решение о предоставлении или отклонении доступа к защищенному ресурсу на основе предоставленных прав.
FilterSecurityInterceptor: фильтр, который проверяет доступ к ресурсам на основе настроек безопасности.
3. Настройка ролей и прав доступа
Spring Security поддерживает настройку через Java-код (Java Config) и XML.
3.1 Подключение Spring Security
Добавьте зависимости в pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
3.2 Создание конфигурационного класса
Конфигурация Spring Security осуществляется с помощью аннотации @EnableWebSecurity и наследования от класса WebSecurityConfigurerAdapter.
Пример базовой конфигурации:
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;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN") // Только для ADMIN
.antMatchers("/user/**").hasRole("USER") // Только для USER
.antMatchers("/public/**").permitAll() // Доступ для всех
.anyRequest().authenticated() // Все остальные запросы требуют аутентификации
.and()
.formLogin() // Включить форму логина
.and()
.logout().permitAll(); // Разрешить logout для всех
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("admin").password(passwordEncoder().encode("adminPass")).roles("ADMIN")
.and()
.withUser("user").password(passwordEncoder().encode("userPass")).roles("USER");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
4. Роли и права: тонкая настройка
Роли (ROLE_*) — это абстракция для группировки прав. Spring Security требует, чтобы роли начинались с префикса ROLE_.
4.1 Настройка прав доступа через аннотации
Spring Security поддерживает аннотации для определения прав доступа на уровне методов.
Включение поддержки аннотаций:
В классе конфигурации добавьте @EnableGlobalMethodSecurity:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// Конфигурация как ранее
}
#Java #Training #Spring #Security #Security_Roles
Использование аннотаций в методах:
4.2 Определение прав доступа (Authorities)
Вместо простого использования ролей можно настроить более тонкие права:
5. Настройка пользовательской аутентификации и хранения данных
В реальных приложениях данные о пользователях и ролях хранятся в базе данных.
5.1 Создание модели пользователя
5.2 Создание модели роли
5.3 Создание пользовательского UserDetailsService
5.4 Использование кастомного сервиса в конфигурации
6. Защита REST API
Если вы разрабатываете REST API, можно отключить CSRF и использовать статeless-сессию:
#Java #Training #Spring #Security #Security_Roles
@Service
public class MyService {
@PreAuthorize("hasRole('ADMIN')")
public void adminOnlyMethod() {
// Только для ADMIN
}
@PreAuthorize("hasAuthority('PERMISSION_VIEW')")
public void specificPermissionMethod() {
// Проверка конкретного разрешения
}
@PostAuthorize("returnObject.owner == authentication.name")
public MyEntity getEntity() {
// Проверка после выполнения метода
}
}
4.2 Определение прав доступа (Authorities)
Вместо простого использования ролей можно настроить более тонкие права:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("admin").password(passwordEncoder().encode("adminPass")).authorities("ROLE_ADMIN", "PERMISSION_READ", "PERMISSION_WRITE")
.and()
.withUser("user").password(passwordEncoder().encode("userPass")).authorities("ROLE_USER", "PERMISSION_READ");
}
5. Настройка пользовательской аутентификации и хранения данных
В реальных приложениях данные о пользователях и ролях хранятся в базе данных.
5.1 Создание модели пользователя
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private boolean enabled;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "user_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<Role> roles;
// Геттеры и сеттеры
}
5.2 Создание модели роли
@Entity
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany(mappedBy = "roles")
private Set<User> users;
// Геттеры и сеттеры
}
5.3 Создание пользовательского UserDetailsService
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
return new org.springframework.security.core.userdetails.User(
user.getUsername(),
user.getPassword(),
mapRolesToAuthorities(user.getRoles())
);
}
private Collection<? extends GrantedAuthority> mapRolesToAuthorities(Collection<Role> roles) {
return roles.stream()
.map(role -> new SimpleGrantedAuthority(role.getName()))
.collect(Collectors.toList());
}
}
5.4 Использование кастомного сервиса в конфигурации
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
}
6. Защита REST API
Если вы разрабатываете REST API, можно отключить CSRF и использовать статeless-сессию:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/user/**").hasRole("USER")
.antMatchers("/api/public/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic(); // Для простоты базовая аутентификация
}
#Java #Training #Spring #Security #Security_Roles
This media is not supported in your browser
VIEW IN TELEGRAM
Всем доброго воскресения! 🖐
Сегодня в 16:00 я вновь жду всех Вас на встречу!
Темы сегодняшней встречи:
🔹 зачем таким как мы удаленный сервер и как его настроить для минимально приемлемой работы
🔹 что такое CI/CD и при чем тут Jenkins
🔹 вспомним о существовании Docker, потыкаем его в разные команды
🔹 создадим минимально рабочий проект на Spring и настроим его непрерывную интеграцию и непрерывное развертывание в контейнер
🔹 просто пообщаемся в хорошей компании IT-шников
Жду конечно же всех🫵
(но придут как всегда единицы😡)
Сегодня в 16:00 я вновь жду всех Вас на встречу!
Темы сегодняшней встречи:
🔹 зачем таким как мы удаленный сервер и как его настроить для минимально приемлемой работы
🔹 что такое CI/CD и при чем тут Jenkins
🔹 вспомним о существовании Docker, потыкаем его в разные команды
🔹 создадим минимально рабочий проект на Spring и настроим его непрерывную интеграцию и непрерывное развертывание в контейнер
🔹 просто пообщаемся в хорошей компании IT-шников
Жду конечно же всех🫵
Изучаем CI/CD. Метод для контейнеризации приложения в Docker через Jenkins. Встреча от 15.12.2024
Запись нашей сегодняшней встречи -
YOUTUBE
RUTUBE
Крайне благодарен всем кто пришел, за участие!💪
На сегодняшней встрече мы на примере, разобрали:
— что такое CI/CD и для чего он нужен.
— как поставить Java, Maven, Docker на удаленный сервер.
— как поставить и настроить для работы Jenkins.
— как создать простейшее веб-приложение и задеплоить его на сервер в Docker контейнер, через CI/CD и Jenkins
Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб и рутюб каналы!!!
Ссылка на GitHub - https://github.com/Oleborn/CICDReserch
Всем хорошего настроения! 🫡✌️
Запись нашей сегодняшней встречи -
YOUTUBE
RUTUBE
Крайне благодарен всем кто пришел, за участие!💪
На сегодняшней встрече мы на примере, разобрали:
— что такое CI/CD и для чего он нужен.
— как поставить Java, Maven, Docker на удаленный сервер.
— как поставить и настроить для работы Jenkins.
— как создать простейшее веб-приложение и задеплоить его на сервер в Docker контейнер, через CI/CD и Jenkins
Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб и рутюб каналы!!!
Ссылка на GitHub - https://github.com/Oleborn/CICDReserch
Всем хорошего настроения! 🫡✌️