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

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

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Что выведет код?

import java.util.TreeSet;

public class Task101224_1 {
public static void main(String[] args) {
TreeSet<String> set = new TreeSet<>((s1, s2) -> s2.length() - s1.length());

set.add("one");
set.add("three");
set.add("four");
set.add("two");
set.add("five");

System.out.println(set);
}
}


#Tasks
Лучше б она ему биткоины купить предложила...🧐🤪

https://t.me/Java_for_beginner_dev

#Mems
В рамках дополнительной информации, устраняем пробел в знаниях по настройке поведения JVM.

Управление JVM (Java Virtual Machine) командами

Управление JVM (Java Virtual Machine) командами — это процесс конфигурации работы JVM через параметры, которые передаются при её запуске. Эти параметры позволяют настраивать поведение JVM, включая управление памятью, настройку сборщика мусора, логирование, отладку и безопасность. Все параметры JVM можно разделить на несколько категорий.

1. Основные типы параметров JVM

1.1. Стандартные параметры
Эти параметры поддерживаются всеми JVM и не зависят от конкретной реализации.

Например:
-cp или -classpath — указывает путь к классам и JAR-файлам.
-Dproperty=value — установка пользовательских системных свойств.
-version — выводит версию JVM.
-help — показывает справку по основным параметрам JVM.


Пример:
java -cp myapp.jar -Dconfig.file=app.properties com.example.Main


1.2. Параметры для настройки памяти

Эти параметры позволяют управлять распределением памяти в JVM:
-Xms<size> — начальный размер кучи (heap).
-Xmx<size> — максимальный размер кучи.
-Xss<size> — размер стека для каждого потока.
-XX:MetaspaceSize=<size> — начальный размер метапространства (метаданных классов).
-XX:MaxMetaspaceSize=<size> — максимальный размер метапространства.


Пример:
java -Xms512m -Xmx2g MyApp


1.3. Расширенные параметры (-X и -XX)

Эти параметры специфичны для реализации JVM (обычно HotSpot) и предоставляют дополнительные возможности:
-X параметры: упрощённые параметры, поддерживаемые большинством JVM.
-Xdebug — включает отладку.
-Xloggc:<file> — логирование работы сборщика мусора в файл.
-XX параметры: детальные настройки и эксперименты.
-XX:+UseG1GC — использование сборщика мусора G1.
-XX:ParallelGCThreads=<n> — количество потоков для параллельной сборки мусора.
-XX:+PrintGCDetails — выводит информацию о работе GC.
-XX:+HeapDumpOnOutOfMemoryError — создаёт дамп памяти при переполнении.


Пример:
java -XX:+UseG1GC -XX:+PrintGCDetails -XX:MaxHeapFreeRatio=70 MyApp


1.4. Логирование и диагностика

Эти параметры помогают анализировать производительность и поведение JVM:
-verbose:class — выводит информацию о загрузке классов.
-verbose:gc — выводит информацию о работе сборщика мусора.
-Xlog — гибкое управление логированием (начиная с Java 9).
Пример: -Xlog:gc* для логирования всех событий, связанных с GC.
-XX:+UnlockDiagnosticVMOptions — включает диагностические параметры.
Например: -XX:+PrintCompilation — выводит информацию о компиляции JIT.


Пример:
java -Xlog:gc* MyApp


1.5. Параметры безопасности
-Djava.security.manager — включает менеджер безопасности.
-Djava.security.policy=<file> — указывает путь к файлу политики безопасности.


2. Распределение памяти и работа GC

2.1. Память JVM

JVM делит память на несколько областей:
Heap (куча): для объектов.
Metaspace: для метаданных классов (начиная с Java 8).
Stack: для хранения вызовов методов и локальных переменных.
Native Memory: для работы JVM вне управляемой памяти.


2.2. Управление сборщиком мусора (GC)

Выбор GC сильно влияет на производительность:
-XX:+UseSerialGC — однопоточный сборщик мусора.
-XX:+UseParallelGC — многопоточный, ориентирован на максимальную пропускную способность.
-XX:+UseG1GC — G1 (Garbage-First) для больших приложений.
-XX:+UseZGC — Z Garbage Collector для низкой задержки (Java 11+).
-XX:+UseShenandoahGC — Shenandoah для низкой задержки (Java 12+).


3. Управление через команды операционной системы


Помимо параметров JVM, можно использовать команды ОС для управления процессом:
jps — список запущенных JVM.
jstat — статистика памяти и GC.
jmap — информация о памяти (heap dump).
jstack — вывод стека потоков.
jcmd — универсальный инструмент управления JVM.


4. Советы и рекомендации

Используйте флаги -Xlog вместо устаревших -verbose:gc в современных версиях Java.
Настройка памяти (-Xms и -Xmx) должна учитывать нагрузку приложения.
Анализируйте дампы памяти для отладки утечек.
Включайте диагностику (-XX:+UnlockDiagnosticVMOptions) только для тестирования.


#Java #Training #Medium #JVM_Commands
Основные принципы безопасности

Безопасность приложения должна обеспечиваться на всех уровнях — от архитектуры до шифрования данных.

1. Принципы обеспечения безопасности

1.1 Принцип наименьших привилегий
Каждый пользователь или система должны иметь минимальный набор разрешений, необходимый для выполнения своих задач.
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
);


1.2 Защита от атак CSRF
Spring Security по умолчанию включает защиту от CSRF.
CSRF — это атака, когда злоумышленник подделывает запрос от имени пользователя.

Можно настроить исключение для REST API:
http.csrf().disable();


1.3 Шифрование паролей
Пароли всегда должны храниться в зашифрованном виде. Используйте BCryptPasswordEncoder:
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}


1.4 Аудит и логирование
Всегда логируйте попытки доступа и события безопасности:
http.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.formLogin(form -> form
.successHandler((req, res, auth) -> System.out.println("Login success: " + auth.getName()))
.failureHandler((req, res, ex) -> System.out.println("Login failure: " + ex.getMessage()))
);


2. Шифрование данных

Используйте HTTPS для передачи данных между клиентом и сервером. Это защищает от перехвата данных в сети.

3. Проверка ввода и защита от XSS

Валидируйте входные данные и используйте механизмы защиты от XSS:
Применяйте фильтрацию данных.
Используйте HTML-энкодинг:

String safeContent = HtmlUtils.htmlEscape(unsafeContent);


Пример безопасного REST API с аутентификацией

Создадим REST API, который защищён с помощью JWT.

Шаг 1: Подключение зависимости:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
</dependency>


Шаг 2: Генерация JWT-токена:
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

public class JwtUtil {

private static final String SECRET_KEY = "mySecretKey";

public static String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60)) // 1 час
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}

public static boolean validateToken(String token, String username) {
String extractedUsername = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getSubject();
return username.equals(extractedUsername);
}
}


Шаг 3: Применение токена в безопасности:
@Configuration
public class JwtSecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.addFilter(new JwtAuthenticationFilter())
.sessionManagement().disable();
return http.build();
}
}


#Java #Training #Spring #Security #SecurityPrincipies
Spring Security и его интеграция в проект

Spring Security — это мощный и гибкий фреймворк для обеспечения безопасности приложений на базе Spring. Он предоставляет возможности для аутентификации, авторизации, защиты от атак CSRF, управления сессиями, защиты REST API и многого другого.

Шаг 1: Добавление Spring Security в проект

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

Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>


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


Шаг 2: Настройка Spring Security

Основные классы для настройки безопасности:
SecurityConfig — класс для настройки конфигурации безопасности.
UserDetailsService — сервис для работы с пользователями.
PasswordEncoder — компонент для кодирования паролей.


1. Конфигурация безопасности (Java-based)
Для настройки Spring Security создадим класс SecurityConfig, который будет аннотирован @Configuration и @EnableWebSecurity. Это обеспечит управление конфигурацией безопасности через Java-код.

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.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((requests) -> requests
.requestMatchers("/public/**").permitAll() // Доступ для всех
.anyRequest().authenticated() // Остальные запросы требуют аутентификации
)
.formLogin((form) -> form
.loginPage("/login") // Кастомная страница логина
.permitAll()
)
.logout((logout) -> logout.permitAll());

return http.build();
}

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


2. Реализация 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;

import java.util.Collections;

@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("Пользователь не найден");
}
}
}


#Java #Training #Spring #Security #AddSecurity
Пароль можно закодировать с помощью следующего кода:
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class PasswordEncoderTest {
public static void main(String[] args) {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String rawPassword = "password";
String encodedPassword = encoder.encode(rawPassword);
System.out.println(encodedPassword);
}
}


3. Кастомизация страницы логина
Для создания кастомной страницы логина добавьте следующий контроллер:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class LoginController {

@GetMapping("/login")
public String login() {
return "login"; // Вернет login.html
}
}


Создайте шаблон login.html:


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login</title>
</head>
<body>
<h2>Login Page</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>


#Java #Training #Spring #Security #AddSecurity
Что выведет код?

class Animal1112 {
void sound() {
System.out.println("Animal makes a sound");
}
}

class Dog1112 extends Animal1112 {
@Override
void sound() {
System.out.println("Dog barks");
}

void fetch() {
System.out.println("Dog fetches a ball");
}
}

class Cat1112 extends Animal1112 {
@Override
void sound() {
System.out.println("Cat meows");
}
}

public class Task111224_1 {
public static void main(String[] args) {
Animal1112 animal1 = new Dog1112();
Animal1112 animal2 = new Cat1112();
animal1.sound();
animal2.sound();

if (animal1 instanceof Dog1112) {
((Dog1112) animal1).fetch();
}

if (animal2 instanceof Dog1112) {
((Dog1112) animal2).fetch();
} else {
System.out.println("Not a Dog");
}
}
}


#Tasks
Ну так это ж девопс😂

https://t.me/Java_for_beginner_dev

#Mems
Продолжаем устранять пробелы по управлению JVM командами.

1. Компиляция программ Java

Для компиляции используется команда javac, которая превращает исходный код (.java) в байт-код (.class).

1.1. Основной синтаксис

javac [опции] <файлы.java>


1.2. Основные параметры
-d <директория> — указывает каталог для выходных файлов .class.
javac -d out src/com/example/MyClass.java


-classpath или -cp — задаёт путь к используемым классам и библиотекам.
javac -cp libs/mylib.jar MyProgram.java


-source <версия> — задаёт версию языка Java для исходного кода.
javac -source 11 MyProgram.java


-target <версия> — указывает целевую версию JVM, для которой будет скомпилирован байт-код.

javac -source 11 -target 8 MyProgram.java


-encoding <кодировка> — кодировка исходных файлов (например, UTF-8).
javac -encoding UTF-8 MyProgram.java


-verbose — выводит дополнительную информацию о процессе компиляции.

2. Запуск программы

Для запуска скомпилированного кода используется команда java, которая запускает JVM и исполняет байт-код.

2.1. Основной синтаксис
java [опции] <имя_класса> [аргументы]


2.2. Основные параметры
-classpath или -cp — задаёт путь к классам и библиотекам.
java -cp out:libs/mylib.jar com.example.MyClass


-D<ключ>=<значение> — задаёт системное свойство, доступное через System.getProperty().
java -Dconfig.file=app.properties com.example.MyClass


-X и -XX параметры — для настройки JVM (управление памятью, GC и т.д.).
--enable-preview — включает поддержку экспериментальных функций (начиная с Java 12).

Пример запуска:
java -Xmx2g -cp out:libs/mylib.jar com.example.MainClass arg1 arg2


3. Утилиты для работы с классами

3.1. jar
Утилита для создания, просмотра и распаковки JAR-архивов.

3.1.1. Создание JAR-файла
jar cf myapp.jar -C out .


Здесь:
c — создать JAR.
f — имя выходного файла.
-C <путь> — указать корневую директорию классов.


3.1.2. Просмотр содержимого JAR
jar tf myapp.jar


3.1.3. Добавление манифеста

Манифест определяет точку входа в приложение:
jar cfe myapp.jar com.example.MainClass -C out .


Флаг e указывает класс с методом public static void main(String[] args).

3.2. javadoc
Генерация HTML-документации из Java-комментариев.

Пример:
javadoc -d docs -sourcepath src -subpackages com.example


3.3. javap
Дизассемблер для классов Java.

Пример:
javap -c com.example.MyClass


Флаг -c выводит байт-код методов.

3.4. jdeps
Инструмент для анализа зависимостей классов.

Пример:
jdeps -summary myapp.jar


4. Утилиты для анализа и отладки

4.1. jdb
Отладчик Java. Используется для пошаговой отладки приложения.

Пример запуска:
jdb -classpath out com.example.MainClass


Команды внутри jdb:
stop at com.example.MainClass:15 — установить точку останова на 15-й строке.
run — запустить программу.
step — выполнить следующую строку.


4.2. Инструменты мониторинга JVM
jps — выводит список всех работающих JVM.
jps -v


jstat — статистика памяти и GC.
jstat -gc <pid>


jmap — информация о памяти, снимки heap.
jmap -heap <pid>


jstack — вывод стека потоков.
jstack <pid>


jcmd — универсальная утилита управления JVM.
jcmd <pid> VM.uptime


5. Пример полного цикла работы

Компиляция:
javac -d out -sourcepath src src/com/example/MainClass.java


Создание JAR:
jar cfe myapp.jar com.example.MainClass -C out .


Запуск:
java -cp myapp.jar com.example.MainClass


Мониторинг:
jps
jstat -gc <pid>
jmap -heap <pid>


#Java #Training #Medium #JVM_Commands
Аннотации используемые в Spring Security

1. @EnableWebSecurity

Аннотация @EnableWebSecurity включает поддержку безопасности на уровне веб-приложений. Она сигнализирует Spring, что текущий класс является конфигурацией безопасности, и подготавливает инфраструктуру Spring Security.

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

@Configuration
@EnableWebSecurity
public class SecurityConfig {
// Здесь будут методы настройки безопасности
}


Нюансы:
Без этой аннотации конфигурация безопасности не будет применена.
Аннотация автоматически активирует SpringSecurityFilterChain.


2. @Configuration

Используется для указания, что класс содержит настройки и бины Spring Security.

Пример:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

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


Нюансы:
Это аннотация общего назначения, используется в любой конфигурации Spring, включая Spring Security.
Ее можно комбинировать с
@EnableWebSecurity.

3.
@PreAuthorize

Аннотация @PreAuthorize позволяет выполнять проверку безопасности перед выполнением метода. Условие определяется с помощью SpEL (Spring Expression Language).

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

@Service
public class UserService {

@PreAuthorize("hasRole('ADMIN')")
public void adminOnlyMethod() {
System.out.println("Только для администраторов");
}

@PreAuthorize("#username == authentication.principal.username")
public void userSpecificMethod(String username) {
System.out.println("Только для пользователя: " + username);
}
}


Нюансы:
Требует включения аннотаций на уровне метода: добавьте @EnableGlobalMethodSecurity(prePostEnabled = true) в класс конфигурации.
Поддерживает сложные выражения SpEL.


4. @PostAuthorize

Выполняет проверку безопасности после выполнения метода. Это полезно, если доступ к результату должен зависеть от данных, возвращенных методом.

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

@Service
public class ProductService {

@PostAuthorize("returnObject.owner == authentication.principal.username")
public Product getProductById(Long id) {
// Имитируем возврат продукта
return new Product(id, "username123");
}
}

class Product {
public Long id;
public String owner;

public Product(Long id, String owner) {
this.id = id;
this.owner = owner;
}
}


Нюансы:
Используется реже, так как может повлиять на производительность из-за выполнения после обработки.
Требует
@EnableGlobalMethodSecurity(prePostEnabled = true).

5. @Secured

Аннотация @Secured ограничивает доступ к методам на основе ролей. В отличие от @PreAuthorize, она не поддерживает SpEL.

Пример:
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;

@Service
public class ReportService {

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

@Secured({"ROLE_USER", "ROLE_MANAGER"})
public void generateUserReport() {
System.out.println("Отчет для пользователя или менеджера");
}
}


Нюансы:
Для использования @Secured необходимо включить метод-базированную безопасность:
@EnableGlobalMethodSecurity(securedEnabled = true)


Роли должны быть указаны с префиксом ROLE_.

#Java #Training #Spring #Security #Security_Annotations
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
Что выведет код?

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
Ты же программист😂

https://t.me/Java_for_beginner_dev

#Mems
Проверка подлинности пользователя в 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