diff --git a/2023-09/spring-25-SS-auth/WebFlux/pom.xml b/2023-09/spring-25-SS-auth/WebFlux/pom.xml
new file mode 100644
index 00000000..f6572b55
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/WebFlux/pom.xml
@@ -0,0 +1,67 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-framework-27-webflux
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.springframework.security
+ spring-security-core
+
+
+ org.springframework.security
+ spring-security-config
+
+
+ org.springframework.security
+ spring-security-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb-reactive
+
+
+
+ de.flapdoodle.embed
+ de.flapdoodle.embed.mongo
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+ spring-milestone
+ http://repo.spring.io/milestone
+
+
+
diff --git a/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/WebFluxStarter.java b/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/WebFluxStarter.java
new file mode 100644
index 00000000..7a06898e
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/WebFluxStarter.java
@@ -0,0 +1,22 @@
+package ru.otus.spring;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.web.reactive.function.server.RouterFunction;
+import org.springframework.web.reactive.function.server.RouterFunctions;
+import org.springframework.web.reactive.function.server.ServerResponse;
+
+@SpringBootApplication
+public class WebFluxStarter {
+
+ public static void main( String[] args ) {
+ SpringApplication.run( WebFluxStarter.class );
+ }
+
+ @Bean
+ RouterFunction staticResourceRouter() {
+ return RouterFunctions.resources( "/**.html", new ClassPathResource( "static/" ) );
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/data/Person.java b/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/data/Person.java
new file mode 100644
index 00000000..bedf08b0
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/data/Person.java
@@ -0,0 +1,41 @@
+package ru.otus.spring.data;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document
+public class Person {
+
+ @Id
+ private String id;
+
+ private String name;
+
+ public Person() {
+ }
+
+ public Person( String name ) {
+ this.name = name;
+ }
+
+ public Person( String id, String name ) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId( String id ) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName( String name ) {
+ this.name = name;
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/data/PersonRepository.java b/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/data/PersonRepository.java
new file mode 100644
index 00000000..8f5f3d67
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/data/PersonRepository.java
@@ -0,0 +1,11 @@
+package ru.otus.spring.data;
+
+import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
+import org.springframework.stereotype.Repository;
+import reactor.core.publisher.Mono;
+
+@Repository
+public interface PersonRepository extends ReactiveMongoRepository {
+
+ Mono findByName( String string );
+}
diff --git a/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/rest/PersonController.java b/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/rest/PersonController.java
new file mode 100644
index 00000000..7af4b0a9
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/rest/PersonController.java
@@ -0,0 +1,34 @@
+package ru.otus.spring.rest;
+
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import ru.otus.spring.data.Person;
+import ru.otus.spring.data.PersonRepository;
+
+@RestController
+public class PersonController {
+
+ private final PersonRepository personRepository;
+
+ public PersonController( PersonRepository personRepository ) {
+ this.personRepository = personRepository;
+ }
+
+ @GetMapping("/person")
+ public Flux getAll() {
+ return personRepository.findAll();
+ }
+
+ @GetMapping("/person/find")
+ public Mono find( @RequestParam("name") String name ) {
+ return personRepository.findByName( name )
+ .cache();
+ }
+
+
+ @PostMapping("/person")
+ public Mono savePerson( @RequestBody Person person ) {
+ return personRepository.save( person );
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/security/SecurityConfiguration.java b/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/security/SecurityConfiguration.java
new file mode 100644
index 00000000..545dd650
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/WebFlux/src/main/java/ru/otus/spring/security/SecurityConfiguration.java
@@ -0,0 +1,47 @@
+package ru.otus.spring.security;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
+import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
+import org.springframework.security.config.web.server.ServerHttpSecurity;
+import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
+import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.crypto.password.NoOpPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.server.SecurityWebFilterChain;
+
+@EnableWebFluxSecurity
+@EnableReactiveMethodSecurity
+public class SecurityConfiguration {
+
+ @Bean
+ public SecurityWebFilterChain springWebFilterChain( ServerHttpSecurity http ) {
+ return http
+ .authorizeExchange()
+ .pathMatchers( HttpMethod.GET, "/authenticated.html" ).hasRole( "USER" )
+ // anonymous
+ .anyExchange().permitAll()
+ .and()
+ .httpBasic()
+ .and()
+ .build();
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return NoOpPasswordEncoder.getInstance();
+ }
+
+ @Bean
+ public ReactiveUserDetailsService userDetailsService() {
+ UserDetails user = User
+ .withUsername( "user" )
+ .password( "password" )
+ .roles( "USER" )
+ .build();
+ return new MapReactiveUserDetailsService( user );
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/WebFlux/src/main/resources/application.yml b/2023-09/spring-25-SS-auth/WebFlux/src/main/resources/application.yml
new file mode 100644
index 00000000..e8d496cc
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/WebFlux/src/main/resources/application.yml
@@ -0,0 +1 @@
+spring.mongodb.embedded.version: 3.5.5
\ No newline at end of file
diff --git a/2023-09/spring-25-SS-auth/WebFlux/src/main/resources/static/authenticated.html b/2023-09/spring-25-SS-auth/WebFlux/src/main/resources/static/authenticated.html
new file mode 100644
index 00000000..9f8b0d7e
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/WebFlux/src/main/resources/static/authenticated.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Только для авторизованных
+
+
diff --git a/2023-09/spring-25-SS-auth/WebFlux/src/main/resources/static/index.html b/2023-09/spring-25-SS-auth/WebFlux/src/main/resources/static/index.html
new file mode 100644
index 00000000..a89ba331
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/WebFlux/src/main/resources/static/index.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+/public.html
+
+/authenticated.html
+
+
diff --git a/2023-09/spring-25-SS-auth/WebFlux/src/main/resources/static/public.html b/2023-09/spring-25-SS-auth/WebFlux/src/main/resources/static/public.html
new file mode 100644
index 00000000..77188469
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/WebFlux/src/main/resources/static/public.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Доступен всем
+
+
diff --git a/2023-09/spring-25-SS-auth/classwork/pom.xml b/2023-09/spring-25-SS-auth/classwork/pom.xml
new file mode 100644
index 00000000..767f0081
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/pom.xml
@@ -0,0 +1,54 @@
+
+
+ 4.0.0
+
+ ru.otus
+ classwork
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.8
+
+
+
+
+ UTF-8
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/SpringSecurityAuthorization.java b/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/SpringSecurityAuthorization.java
new file mode 100644
index 00000000..6b3bf909
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/SpringSecurityAuthorization.java
@@ -0,0 +1,13 @@
+package ru.otus.spring;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringSecurityAuthorization {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringSecurityAuthorization.class);
+ }
+
+}
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/controller/PagesController.java b/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/controller/PagesController.java
new file mode 100644
index 00000000..c7e8419c
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/controller/PagesController.java
@@ -0,0 +1,59 @@
+package ru.otus.spring.controller;
+
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import ru.otus.spring.service.MyService;
+
+@Controller
+public class PagesController {
+
+ private final MyService myService;
+
+ public PagesController(MyService myService) {
+ this.myService = myService;
+ }
+
+ @GetMapping("/")
+ public String indexPage() {
+ return "index";
+ }
+
+ @GetMapping("/public")
+ public String publicPage() {
+ return "public";
+ }
+
+ @GetMapping("/user")
+ public String userPage() {
+ myService.onlyUser();
+ return "user";
+ }
+
+ @GetMapping("/manager")
+ public String managerPage() {
+ return "manager";
+ }
+
+ @GetMapping("/admin")
+ //@Secured( "ADMIN" )
+ public String adminPage() {
+ myService.onlyUser();
+ //myService.onlyAdmin();
+ return "admin";
+ }
+
+ @GetMapping("/authenticated")
+ public String authenticatedPage() {
+ UserDetails userDetails = (UserDetails) SecurityContextHolder
+ .getContext().getAuthentication().getPrincipal();
+ System.out.println(userDetails.getUsername());
+ return "authenticated";
+ }
+
+ @GetMapping("/success")
+ public String successPage() {
+ return "success";
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/controller/SecurityControllerAdvice.java b/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/controller/SecurityControllerAdvice.java
new file mode 100644
index 00000000..bdbb5ea3
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/controller/SecurityControllerAdvice.java
@@ -0,0 +1,16 @@
+package ru.otus.spring.controller;
+
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+import java.util.Optional;
+
+@ControllerAdvice
+public class SecurityControllerAdvice {
+ @ExceptionHandler(AccessDeniedException.class)
+ public ResponseEntity accessError() {
+ return ResponseEntity.of(Optional.of("Неудачник"));
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/security/MethodSecurityConfiguration.java b/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/security/MethodSecurityConfiguration.java
new file mode 100644
index 00000000..cacbe63f
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/security/MethodSecurityConfiguration.java
@@ -0,0 +1,10 @@
+package ru.otus.spring.security;
+
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+
+@EnableGlobalMethodSecurity(
+ securedEnabled = true,
+ prePostEnabled = true
+)
+public class MethodSecurityConfiguration {
+}
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/security/SecurityConfiguration.java b/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/security/SecurityConfiguration.java
new file mode 100644
index 00000000..680c68ab
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/security/SecurityConfiguration.java
@@ -0,0 +1,45 @@
+package ru.otus.spring.security;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
+
+import java.util.ArrayList;
+
+@EnableWebSecurity
+public class SecurityConfiguration {
+
+ @Bean
+ public SecurityFilterChain securityFilterChain( HttpSecurity http ) throws Exception {
+ http
+ .csrf().disable()
+ .authorizeHttpRequests( ( authorize ) -> authorize
+ .antMatchers( "/public", "/" ).permitAll()
+ .antMatchers( "/authenticated", "/success" ).authenticated()
+ .antMatchers( "/manager" ).hasAnyRole( "MANAGER" )
+ .antMatchers( "/user" ).hasAnyRole( "ADMIN", "USER" )
+ .anyRequest().denyAll()
+ )
+ .formLogin()
+
+ ;
+ return http.build();
+ }
+
+ @Bean
+ public InMemoryUserDetailsManager userDetailsService() {
+ var users = new ArrayList();
+ users.add( User
+ .withDefaultPasswordEncoder().username( "admin" ).password( "password" ).roles( "ADMIN" )
+ .build() );
+ users.add( User
+ .withDefaultPasswordEncoder().username( "user" ).password( "password" ).roles( "USER" )
+ .build() );
+ return new InMemoryUserDetailsManager( users );
+
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/service/MyService.java b/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/service/MyService.java
new file mode 100644
index 00000000..9c108f59
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/java/ru/otus/spring/service/MyService.java
@@ -0,0 +1,17 @@
+package ru.otus.spring.service;
+
+import org.springframework.security.access.annotation.Secured;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Service;
+
+@Service
+public class MyService {
+ @PreAuthorize("hasRole('ROLE_USER') && {new java.util.Random().nextInt()%2 == 0}")
+ public String onlyUser() {
+ return "My love";
+ }
+
+ @Secured("ADMIN")
+ public void onlyAdmin() {
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/admin.html b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/admin.html
new file mode 100644
index 00000000..aa1c9563
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/admin.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Страница с доступом только админу
+
+
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/authenticated.html b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/authenticated.html
new file mode 100644
index 00000000..e4756c01
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/authenticated.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Только для аторизованных
+
+
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/error.html b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/error.html
new file mode 100644
index 00000000..f28b51df
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/error.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Вам доступ запрещён!
+
+
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/index.html b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/index.html
new file mode 100644
index 00000000..d4c54ecd
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+/public
+
+/authenticated
+
+/user
+
+/admin
+
+
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/manager.html b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/manager.html
new file mode 100644
index 00000000..dd4a77af
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/manager.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Доступ к MANAGER
+
+
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/public.html b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/public.html
new file mode 100644
index 00000000..77188469
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/public.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Доступен всем
+
+
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/success.html b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/success.html
new file mode 100644
index 00000000..4e2a37cd
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/success.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Вы успешно вошли !
+
+
diff --git a/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/user.html b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/user.html
new file mode 100644
index 00000000..a794bc2d
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/classwork/src/main/resources/templates/user.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Доступ к USER
+
+
diff --git a/2023-09/spring-25-SS-auth/oauth/pom.xml b/2023-09/spring-25-SS-auth/oauth/pom.xml
new file mode 100644
index 00000000..36300726
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/oauth/pom.xml
@@ -0,0 +1,87 @@
+
+
+ 4.0.0
+
+ ru.otus
+ spring-framework-27-oauth
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.6.10
+
+
+
+ 2.6.11
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-oauth2-client
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+
+
+
+
+ org.springdoc
+ springdoc-openapi-ui
+ 1.6.9
+
+
+
+ org.webjars
+ jquery
+ 3.4.1
+
+
+ org.webjars
+ bootstrap
+ 4.3.1
+
+
+ org.webjars
+ webjars-locator-core
+
+
+ org.webjars
+ js-cookie
+ 2.1.0
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2023-09/spring-25-SS-auth/oauth/src/main/java/ru/otus/spring/sso/GithubApplication.java b/2023-09/spring-25-SS-auth/oauth/src/main/java/ru/otus/spring/sso/GithubApplication.java
new file mode 100644
index 00000000..7a69b021
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/oauth/src/main/java/ru/otus/spring/sso/GithubApplication.java
@@ -0,0 +1,13 @@
+package ru.otus.spring.sso;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class GithubApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run( GithubApplication.class, args);
+ }
+
+}
\ No newline at end of file
diff --git a/2023-09/spring-25-SS-auth/oauth/src/main/java/ru/otus/spring/sso/controller/IndexController.java b/2023-09/spring-25-SS-auth/oauth/src/main/java/ru/otus/spring/sso/controller/IndexController.java
new file mode 100644
index 00000000..a6e55cd2
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/oauth/src/main/java/ru/otus/spring/sso/controller/IndexController.java
@@ -0,0 +1,13 @@
+package ru.otus.spring.sso.controller;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+
+@Controller
+public class IndexController {
+
+ @GetMapping("/")
+ public String indexPage() {
+ return "index";
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/oauth/src/main/java/ru/otus/spring/sso/controller/UserController.java b/2023-09/spring-25-SS-auth/oauth/src/main/java/ru/otus/spring/sso/controller/UserController.java
new file mode 100644
index 00000000..a99dc54d
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/oauth/src/main/java/ru/otus/spring/sso/controller/UserController.java
@@ -0,0 +1,17 @@
+package ru.otus.spring.sso.controller;
+
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.security.oauth2.core.user.OAuth2User;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Collections;
+import java.util.Map;
+
+@RestController
+public class UserController {
+ @GetMapping("/user")
+ public Map user( @AuthenticationPrincipal OAuth2User principal) {
+ return Collections.singletonMap("name", principal.getAttribute("name"));
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/oauth/src/main/java/ru/otus/spring/sso/security/SecurityConfig.java b/2023-09/spring-25-SS-auth/oauth/src/main/java/ru/otus/spring/sso/security/SecurityConfig.java
new file mode 100644
index 00000000..b357a066
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/oauth/src/main/java/ru/otus/spring/sso/security/SecurityConfig.java
@@ -0,0 +1,26 @@
+package ru.otus.spring.sso.security;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.authentication.HttpStatusEntryPoint;
+
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+ @Override
+ protected void configure( HttpSecurity http ) throws Exception {
+ http
+ .authorizeRequests( a -> a
+ .antMatchers( "/", "/error", "/webjars/**" ).permitAll()
+ .anyRequest().authenticated()
+ )
+ .exceptionHandling( e -> e
+ .authenticationEntryPoint( new HttpStatusEntryPoint( HttpStatus.UNAUTHORIZED ) )
+ )
+ .csrf().disable()
+ .logout( l -> l
+ .logoutSuccessUrl( "/" ).permitAll()
+ )
+
+ .oauth2Login();
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/oauth/src/main/resources/application.yml b/2023-09/spring-25-SS-auth/oauth/src/main/resources/application.yml
new file mode 100644
index 00000000..8ef3c0db
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/oauth/src/main/resources/application.yml
@@ -0,0 +1,13 @@
+spring:
+ security:
+ oauth2:
+ client:
+ registration:
+ github:
+ clientId: fdec09b924be7f214eaa
+ clientSecret: 5436beb72dc2ec7f2320afcab5185c1ea03d484b
+
+logging:
+ level:
+ root: error
+ org.springframework.security: DEBUG
\ No newline at end of file
diff --git a/2023-09/spring-25-SS-auth/oauth/src/main/resources/templates/index.html b/2023-09/spring-25-SS-auth/oauth/src/main/resources/templates/index.html
new file mode 100644
index 00000000..09dae5ba
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/oauth/src/main/resources/templates/index.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+ Demo
+
+
+
+
+
+
+
+
+Demo
+
+
+
\ No newline at end of file
diff --git a/2023-09/spring-25-SS-auth/solution2/pom.xml b/2023-09/spring-25-SS-auth/solution2/pom.xml
new file mode 100644
index 00000000..a2c07373
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/pom.xml
@@ -0,0 +1,54 @@
+
+
+ 4.0.0
+
+ ru.otus
+ solution2
+ 1.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.8
+
+
+
+
+ UTF-8
+ UTF-8
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/SpringSecurityAuthorization.java b/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/SpringSecurityAuthorization.java
new file mode 100644
index 00000000..6b3bf909
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/SpringSecurityAuthorization.java
@@ -0,0 +1,13 @@
+package ru.otus.spring;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringSecurityAuthorization {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringSecurityAuthorization.class);
+ }
+
+}
diff --git a/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/controller/PagesController.java b/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/controller/PagesController.java
new file mode 100644
index 00000000..c2350307
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/controller/PagesController.java
@@ -0,0 +1,56 @@
+package ru.otus.spring.controller;
+
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import ru.otus.spring.service.MyService;
+
+@Controller
+public class PagesController {
+
+ private final MyService myService;
+
+ public PagesController(MyService myService) {
+ this.myService = myService;
+ }
+
+ @GetMapping("/")
+ public String indexPage() {
+ return "index";
+ }
+
+ @GetMapping("/public")
+ public String publicPage() {
+ return "public";
+ }
+
+ @GetMapping("/user")
+ public String userPage() {
+ return "user";
+ }
+
+ @GetMapping("/manager")
+ public String managerPage() {
+ myService.onlyAdmin();
+ return "manager";
+ }
+
+ @GetMapping("/admin")
+ public String adminPage() {
+ return "admin";
+ }
+
+ @GetMapping("/authenticated")
+ public String authenticatedPage() {
+ UserDetails userDetails = (UserDetails) SecurityContextHolder
+ .getContext().getAuthentication().getPrincipal();
+ System.out.println(userDetails.getUsername());
+ return "authenticated";
+ }
+
+ @GetMapping("/success")
+ public String successPage() {
+ return "success";
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/security/MethodSecurityConfiguration.java b/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/security/MethodSecurityConfiguration.java
new file mode 100644
index 00000000..d7fe2d0d
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/security/MethodSecurityConfiguration.java
@@ -0,0 +1,7 @@
+package ru.otus.spring.security;
+
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class MethodSecurityConfiguration {
+}
diff --git a/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/security/SecurityConfiguration.java b/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/security/SecurityConfiguration.java
new file mode 100644
index 00000000..b0dadc85
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/security/SecurityConfiguration.java
@@ -0,0 +1,51 @@
+package ru.otus.spring.security;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
+
+import java.util.ArrayList;
+
+@EnableWebSecurity
+public class SecurityConfiguration {
+
+
+ @Bean
+ public SecurityFilterChain securityFilterChain( HttpSecurity http ) throws Exception {
+ http
+ .csrf().disable()
+// .sessionManagement().sessionCreationPolicy( SessionCreationPolicy.STATELESS)
+// .and()
+ .authorizeHttpRequests( ( authorize ) -> authorize
+ .antMatchers( "/public", "/" ).permitAll()
+ .antMatchers( "/authenticated", "/success" ).authenticated()
+ .antMatchers( "/manager" ).hasAnyRole( "MANAGER" )
+ .antMatchers( "/user" ).hasAnyRole( "ADMIN", "USER" )
+ .anyRequest().denyAll()
+ )
+ .formLogin()
+
+ ;
+ return http.build();
+ }
+
+ @Bean
+ public InMemoryUserDetailsManager userDetailsService() {
+ var users = new ArrayList();
+ users.add( User
+ .withDefaultPasswordEncoder().username( "admin" ).password( "password" ).roles( "ADMIN" )
+ .build() );
+ users.add( User
+ .withDefaultPasswordEncoder().username( "user" ).password( "password" ).roles( "USER" )
+ .build() );
+ users.add( User
+ .withDefaultPasswordEncoder().username( "manager" ).password( "password" ).roles( "MANAGER", "USER" )
+ .build() );
+ return new InMemoryUserDetailsManager( users );
+
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/service/MyService.java b/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/service/MyService.java
new file mode 100644
index 00000000..3b316f45
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/src/main/java/ru/otus/spring/service/MyService.java
@@ -0,0 +1,12 @@
+package ru.otus.spring.service;
+
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Service;
+
+@Service
+public class MyService {
+
+ @PreAuthorize("hasRole('ADMIN')")
+ public void onlyAdmin() {
+ }
+}
diff --git a/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/admin.html b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/admin.html
new file mode 100644
index 00000000..aa1c9563
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/admin.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Страница с доступом только админу
+
+
diff --git a/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/authenticated.html b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/authenticated.html
new file mode 100644
index 00000000..e4756c01
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/authenticated.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Только для аторизованных
+
+
diff --git a/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/error.html b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/error.html
new file mode 100644
index 00000000..f28b51df
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/error.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Вам доступ запрещён!
+
+
diff --git a/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/index.html b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/index.html
new file mode 100644
index 00000000..9a8b9382
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+/public
+
+/authenticated
+
+/user
+
+/manager
+
+/admin
+
+
diff --git a/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/manager.html b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/manager.html
new file mode 100644
index 00000000..dd4a77af
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/manager.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Доступ к MANAGER
+
+
diff --git a/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/public.html b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/public.html
new file mode 100644
index 00000000..77188469
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/public.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Доступен всем
+
+
diff --git a/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/success.html b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/success.html
new file mode 100644
index 00000000..4e2a37cd
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/success.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Вы успешно вошли !
+
+
diff --git a/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/user.html b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/user.html
new file mode 100644
index 00000000..a794bc2d
--- /dev/null
+++ b/2023-09/spring-25-SS-auth/solution2/src/main/resources/templates/user.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+Доступ к USER
+
+