person = peopleRepository.findByUsername(s);
+
+ if (person.isEmpty())
+ throw new UsernameNotFoundException("User not found");
+
+ return new PersonDetails(person.get());
+ }
+}
diff --git a/JWTApp/src/main/java/ru/alishev/springcourse/FirstSecurityApp/services/RegistrationService.java b/JWTApp/src/main/java/ru/alishev/springcourse/FirstSecurityApp/services/RegistrationService.java
new file mode 100644
index 00000000..38cb0eec
--- /dev/null
+++ b/JWTApp/src/main/java/ru/alishev/springcourse/FirstSecurityApp/services/RegistrationService.java
@@ -0,0 +1,31 @@
+package ru.alishev.springcourse.FirstSecurityApp.services;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import ru.alishev.springcourse.FirstSecurityApp.models.Person;
+import ru.alishev.springcourse.FirstSecurityApp.repositories.PeopleRepository;
+
+/**
+ * @author Neil Alishev
+ */
+@Service
+public class RegistrationService {
+
+ private final PeopleRepository peopleRepository;
+ private final PasswordEncoder passwordEncoder;
+
+ @Autowired
+ public RegistrationService(PeopleRepository peopleRepository, PasswordEncoder passwordEncoder) {
+ this.peopleRepository = peopleRepository;
+ this.passwordEncoder = passwordEncoder;
+ }
+
+ @Transactional
+ public void register(Person person) {
+ person.setPassword(passwordEncoder.encode(person.getPassword()));
+ person.setRole("ROLE_USER");
+ peopleRepository.save(person);
+ }
+}
diff --git a/JWTApp/src/main/java/ru/alishev/springcourse/FirstSecurityApp/util/PersonValidator.java b/JWTApp/src/main/java/ru/alishev/springcourse/FirstSecurityApp/util/PersonValidator.java
new file mode 100644
index 00000000..93694cc9
--- /dev/null
+++ b/JWTApp/src/main/java/ru/alishev/springcourse/FirstSecurityApp/util/PersonValidator.java
@@ -0,0 +1,41 @@
+package ru.alishev.springcourse.FirstSecurityApp.util;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.Errors;
+import org.springframework.validation.Validator;
+import ru.alishev.springcourse.FirstSecurityApp.models.Person;
+import ru.alishev.springcourse.FirstSecurityApp.services.PersonDetailsService;
+
+/**
+ * @author Neil Alishev
+ */
+@Component
+public class PersonValidator implements Validator {
+
+ private final PersonDetailsService personDetailsService;
+
+ @Autowired
+ public PersonValidator(PersonDetailsService personDetailsService) {
+ this.personDetailsService = personDetailsService;
+ }
+
+ @Override
+ public boolean supports(Class> aClass) {
+ return Person.class.equals(aClass);
+ }
+
+ @Override
+ public void validate(Object o, Errors errors) {
+ Person person = (Person) o;
+
+ try {
+ personDetailsService.loadUserByUsername(person.getUsername());
+ } catch (UsernameNotFoundException ignored) {
+ return; // все ок, пользователь не найден
+ }
+
+ errors.rejectValue("username", "", "Человек с таким именем пользователя уже существует");
+ }
+}
diff --git a/JWTApp/src/main/resources/application.properties b/JWTApp/src/main/resources/application.properties
new file mode 100644
index 00000000..97c20e5a
--- /dev/null
+++ b/JWTApp/src/main/resources/application.properties
@@ -0,0 +1,9 @@
+spring.datasource.driverClassName=org.postgresql.Driver
+spring.datasource.url=jdbc:postgresql://localhost:5432/security_app_db
+spring.datasource.username=postgres
+spring.datasource.password=postgres
+
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
+spring.jpa.properties.hibernate.show_sql=true
+
+jwt_secret=SECRET
\ No newline at end of file
diff --git a/JWTApp/src/main/resources/templates/admin.html b/JWTApp/src/main/resources/templates/admin.html
new file mode 100644
index 00000000..4e64e0a1
--- /dev/null
+++ b/JWTApp/src/main/resources/templates/admin.html
@@ -0,0 +1,10 @@
+
+
+
+
+ Admin page
+
+
+Admin page
+
+
\ No newline at end of file
diff --git a/JWTApp/src/main/resources/templates/auth/login.html b/JWTApp/src/main/resources/templates/auth/login.html
new file mode 100644
index 00000000..f1cc287e
--- /dev/null
+++ b/JWTApp/src/main/resources/templates/auth/login.html
@@ -0,0 +1,26 @@
+
+
+
+
+ Login page
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/JWTApp/src/main/resources/templates/auth/registration.html b/JWTApp/src/main/resources/templates/auth/registration.html
new file mode 100644
index 00000000..990ab437
--- /dev/null
+++ b/JWTApp/src/main/resources/templates/auth/registration.html
@@ -0,0 +1,27 @@
+
+
+
+
+ Registration
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/JWTApp/src/main/resources/templates/hello.html b/JWTApp/src/main/resources/templates/hello.html
new file mode 100644
index 00000000..b5f49686
--- /dev/null
+++ b/JWTApp/src/main/resources/templates/hello.html
@@ -0,0 +1,14 @@
+
+
+
+
+ Hello
+
+
+Hello world!
+
+
+
+
\ No newline at end of file
diff --git a/JWTApp/src/test/java/ru/alishev/springcourse/FirstSecurityApp/SpringSecurityAppTests.java b/JWTApp/src/test/java/ru/alishev/springcourse/FirstSecurityApp/SpringSecurityAppTests.java
new file mode 100644
index 00000000..ffd4aff2
--- /dev/null
+++ b/JWTApp/src/test/java/ru/alishev/springcourse/FirstSecurityApp/SpringSecurityAppTests.java
@@ -0,0 +1,13 @@
+package ru.alishev.springcourse.FirstSecurityApp;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class SpringSecurityAppTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}