diff --git a/2023-01/spring-26/WebFlux/pom.xml b/2023-01/spring-26/WebFlux/pom.xml new file mode 100644 index 00000000..f6572b55 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/WebFlux/src/main/java/ru/otus/spring/WebFluxStarter.java b/2023-01/spring-26/WebFlux/src/main/java/ru/otus/spring/WebFluxStarter.java new file mode 100644 index 00000000..7a06898e --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/WebFlux/src/main/java/ru/otus/spring/data/Person.java b/2023-01/spring-26/WebFlux/src/main/java/ru/otus/spring/data/Person.java new file mode 100644 index 00000000..bedf08b0 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/WebFlux/src/main/java/ru/otus/spring/data/PersonRepository.java b/2023-01/spring-26/WebFlux/src/main/java/ru/otus/spring/data/PersonRepository.java new file mode 100644 index 00000000..8f5f3d67 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/WebFlux/src/main/java/ru/otus/spring/rest/PersonController.java b/2023-01/spring-26/WebFlux/src/main/java/ru/otus/spring/rest/PersonController.java new file mode 100644 index 00000000..7af4b0a9 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/WebFlux/src/main/java/ru/otus/spring/security/SecurityConfiguration.java b/2023-01/spring-26/WebFlux/src/main/java/ru/otus/spring/security/SecurityConfiguration.java new file mode 100644 index 00000000..545dd650 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/WebFlux/src/main/resources/application.yml b/2023-01/spring-26/WebFlux/src/main/resources/application.yml new file mode 100644 index 00000000..e8d496cc --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/WebFlux/src/main/resources/static/authenticated.html b/2023-01/spring-26/WebFlux/src/main/resources/static/authenticated.html new file mode 100644 index 00000000..9f8b0d7e --- /dev/null +++ b/2023-01/spring-26/WebFlux/src/main/resources/static/authenticated.html @@ -0,0 +1,9 @@ + + + + + + +Только для авторизованных + + diff --git a/2023-01/spring-26/WebFlux/src/main/resources/static/index.html b/2023-01/spring-26/WebFlux/src/main/resources/static/index.html new file mode 100644 index 00000000..a89ba331 --- /dev/null +++ b/2023-01/spring-26/WebFlux/src/main/resources/static/index.html @@ -0,0 +1,11 @@ + + + + + + +/public.html +
+/authenticated.html + + diff --git a/2023-01/spring-26/WebFlux/src/main/resources/static/public.html b/2023-01/spring-26/WebFlux/src/main/resources/static/public.html new file mode 100644 index 00000000..77188469 --- /dev/null +++ b/2023-01/spring-26/WebFlux/src/main/resources/static/public.html @@ -0,0 +1,9 @@ + + + + + + +Доступен всем + + diff --git a/2023-01/spring-26/classwork/pom.xml b/2023-01/spring-26/classwork/pom.xml new file mode 100644 index 00000000..767f0081 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/classwork/src/main/java/ru/otus/spring/SpringSecurityAuthorization.java b/2023-01/spring-26/classwork/src/main/java/ru/otus/spring/SpringSecurityAuthorization.java new file mode 100644 index 00000000..6b3bf909 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/classwork/src/main/java/ru/otus/spring/controller/PagesController.java b/2023-01/spring-26/classwork/src/main/java/ru/otus/spring/controller/PagesController.java new file mode 100644 index 00000000..c7e8419c --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/classwork/src/main/java/ru/otus/spring/controller/SecurityControllerAdvice.java b/2023-01/spring-26/classwork/src/main/java/ru/otus/spring/controller/SecurityControllerAdvice.java new file mode 100644 index 00000000..bdbb5ea3 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/classwork/src/main/java/ru/otus/spring/security/MethodSecurityConfiguration.java b/2023-01/spring-26/classwork/src/main/java/ru/otus/spring/security/MethodSecurityConfiguration.java new file mode 100644 index 00000000..cacbe63f --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/classwork/src/main/java/ru/otus/spring/security/SecurityConfiguration.java b/2023-01/spring-26/classwork/src/main/java/ru/otus/spring/security/SecurityConfiguration.java new file mode 100644 index 00000000..680c68ab --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/classwork/src/main/java/ru/otus/spring/service/MyService.java b/2023-01/spring-26/classwork/src/main/java/ru/otus/spring/service/MyService.java new file mode 100644 index 00000000..9c108f59 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/classwork/src/main/resources/templates/admin.html b/2023-01/spring-26/classwork/src/main/resources/templates/admin.html new file mode 100644 index 00000000..aa1c9563 --- /dev/null +++ b/2023-01/spring-26/classwork/src/main/resources/templates/admin.html @@ -0,0 +1,9 @@ + + + + + + +Страница с доступом только админу + + diff --git a/2023-01/spring-26/classwork/src/main/resources/templates/authenticated.html b/2023-01/spring-26/classwork/src/main/resources/templates/authenticated.html new file mode 100644 index 00000000..e4756c01 --- /dev/null +++ b/2023-01/spring-26/classwork/src/main/resources/templates/authenticated.html @@ -0,0 +1,9 @@ + + + + + + +Только для аторизованных + + diff --git a/2023-01/spring-26/classwork/src/main/resources/templates/error.html b/2023-01/spring-26/classwork/src/main/resources/templates/error.html new file mode 100644 index 00000000..f28b51df --- /dev/null +++ b/2023-01/spring-26/classwork/src/main/resources/templates/error.html @@ -0,0 +1,9 @@ + + + + + + +Вам доступ запрещён! + + diff --git a/2023-01/spring-26/classwork/src/main/resources/templates/index.html b/2023-01/spring-26/classwork/src/main/resources/templates/index.html new file mode 100644 index 00000000..d4c54ecd --- /dev/null +++ b/2023-01/spring-26/classwork/src/main/resources/templates/index.html @@ -0,0 +1,15 @@ + + + + + + +/public +
+/authenticated +
+/user +
+/admin + + diff --git a/2023-01/spring-26/classwork/src/main/resources/templates/manager.html b/2023-01/spring-26/classwork/src/main/resources/templates/manager.html new file mode 100644 index 00000000..dd4a77af --- /dev/null +++ b/2023-01/spring-26/classwork/src/main/resources/templates/manager.html @@ -0,0 +1,9 @@ + + + + + + +Доступ к MANAGER + + diff --git a/2023-01/spring-26/classwork/src/main/resources/templates/public.html b/2023-01/spring-26/classwork/src/main/resources/templates/public.html new file mode 100644 index 00000000..77188469 --- /dev/null +++ b/2023-01/spring-26/classwork/src/main/resources/templates/public.html @@ -0,0 +1,9 @@ + + + + + + +Доступен всем + + diff --git a/2023-01/spring-26/classwork/src/main/resources/templates/success.html b/2023-01/spring-26/classwork/src/main/resources/templates/success.html new file mode 100644 index 00000000..4e2a37cd --- /dev/null +++ b/2023-01/spring-26/classwork/src/main/resources/templates/success.html @@ -0,0 +1,9 @@ + + + + + + +Вы успешно вошли ! + + diff --git a/2023-01/spring-26/classwork/src/main/resources/templates/user.html b/2023-01/spring-26/classwork/src/main/resources/templates/user.html new file mode 100644 index 00000000..a794bc2d --- /dev/null +++ b/2023-01/spring-26/classwork/src/main/resources/templates/user.html @@ -0,0 +1,9 @@ + + + + + + +Доступ к USER + + diff --git a/2023-01/spring-26/oauth/pom.xml b/2023-01/spring-26/oauth/pom.xml new file mode 100644 index 00000000..36300726 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/oauth/src/main/java/ru/otus/spring/sso/GithubApplication.java b/2023-01/spring-26/oauth/src/main/java/ru/otus/spring/sso/GithubApplication.java new file mode 100644 index 00000000..7a69b021 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/oauth/src/main/java/ru/otus/spring/sso/controller/IndexController.java b/2023-01/spring-26/oauth/src/main/java/ru/otus/spring/sso/controller/IndexController.java new file mode 100644 index 00000000..a6e55cd2 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/oauth/src/main/java/ru/otus/spring/sso/controller/UserController.java b/2023-01/spring-26/oauth/src/main/java/ru/otus/spring/sso/controller/UserController.java new file mode 100644 index 00000000..a99dc54d --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/oauth/src/main/java/ru/otus/spring/sso/security/SecurityConfig.java b/2023-01/spring-26/oauth/src/main/java/ru/otus/spring/sso/security/SecurityConfig.java new file mode 100644 index 00000000..b357a066 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/oauth/src/main/resources/application.yml b/2023-01/spring-26/oauth/src/main/resources/application.yml new file mode 100644 index 00000000..8ef3c0db --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/oauth/src/main/resources/templates/index.html b/2023-01/spring-26/oauth/src/main/resources/templates/index.html new file mode 100644 index 00000000..09dae5ba --- /dev/null +++ b/2023-01/spring-26/oauth/src/main/resources/templates/index.html @@ -0,0 +1,18 @@ + + + + + + Demo + + + + + + + + +

Demo

+
+ + \ No newline at end of file diff --git a/2023-01/spring-26/solution2/pom.xml b/2023-01/spring-26/solution2/pom.xml new file mode 100644 index 00000000..a2c07373 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/solution2/src/main/java/ru/otus/spring/SpringSecurityAuthorization.java b/2023-01/spring-26/solution2/src/main/java/ru/otus/spring/SpringSecurityAuthorization.java new file mode 100644 index 00000000..6b3bf909 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/solution2/src/main/java/ru/otus/spring/controller/PagesController.java b/2023-01/spring-26/solution2/src/main/java/ru/otus/spring/controller/PagesController.java new file mode 100644 index 00000000..c2350307 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/solution2/src/main/java/ru/otus/spring/security/MethodSecurityConfiguration.java b/2023-01/spring-26/solution2/src/main/java/ru/otus/spring/security/MethodSecurityConfiguration.java new file mode 100644 index 00000000..d7fe2d0d --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/solution2/src/main/java/ru/otus/spring/security/SecurityConfiguration.java b/2023-01/spring-26/solution2/src/main/java/ru/otus/spring/security/SecurityConfiguration.java new file mode 100644 index 00000000..b0dadc85 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/solution2/src/main/java/ru/otus/spring/service/MyService.java b/2023-01/spring-26/solution2/src/main/java/ru/otus/spring/service/MyService.java new file mode 100644 index 00000000..3b316f45 --- /dev/null +++ b/2023-01/spring-26/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-01/spring-26/solution2/src/main/resources/templates/admin.html b/2023-01/spring-26/solution2/src/main/resources/templates/admin.html new file mode 100644 index 00000000..aa1c9563 --- /dev/null +++ b/2023-01/spring-26/solution2/src/main/resources/templates/admin.html @@ -0,0 +1,9 @@ + + + + + + +Страница с доступом только админу + + diff --git a/2023-01/spring-26/solution2/src/main/resources/templates/authenticated.html b/2023-01/spring-26/solution2/src/main/resources/templates/authenticated.html new file mode 100644 index 00000000..e4756c01 --- /dev/null +++ b/2023-01/spring-26/solution2/src/main/resources/templates/authenticated.html @@ -0,0 +1,9 @@ + + + + + + +Только для аторизованных + + diff --git a/2023-01/spring-26/solution2/src/main/resources/templates/error.html b/2023-01/spring-26/solution2/src/main/resources/templates/error.html new file mode 100644 index 00000000..f28b51df --- /dev/null +++ b/2023-01/spring-26/solution2/src/main/resources/templates/error.html @@ -0,0 +1,9 @@ + + + + + + +Вам доступ запрещён! + + diff --git a/2023-01/spring-26/solution2/src/main/resources/templates/index.html b/2023-01/spring-26/solution2/src/main/resources/templates/index.html new file mode 100644 index 00000000..9a8b9382 --- /dev/null +++ b/2023-01/spring-26/solution2/src/main/resources/templates/index.html @@ -0,0 +1,17 @@ + + + + + + +/public +
+/authenticated +
+/user +
+/manager +
+/admin + + diff --git a/2023-01/spring-26/solution2/src/main/resources/templates/manager.html b/2023-01/spring-26/solution2/src/main/resources/templates/manager.html new file mode 100644 index 00000000..dd4a77af --- /dev/null +++ b/2023-01/spring-26/solution2/src/main/resources/templates/manager.html @@ -0,0 +1,9 @@ + + + + + + +Доступ к MANAGER + + diff --git a/2023-01/spring-26/solution2/src/main/resources/templates/public.html b/2023-01/spring-26/solution2/src/main/resources/templates/public.html new file mode 100644 index 00000000..77188469 --- /dev/null +++ b/2023-01/spring-26/solution2/src/main/resources/templates/public.html @@ -0,0 +1,9 @@ + + + + + + +Доступен всем + + diff --git a/2023-01/spring-26/solution2/src/main/resources/templates/success.html b/2023-01/spring-26/solution2/src/main/resources/templates/success.html new file mode 100644 index 00000000..4e2a37cd --- /dev/null +++ b/2023-01/spring-26/solution2/src/main/resources/templates/success.html @@ -0,0 +1,9 @@ + + + + + + +Вы успешно вошли ! + + diff --git a/2023-01/spring-26/solution2/src/main/resources/templates/user.html b/2023-01/spring-26/solution2/src/main/resources/templates/user.html new file mode 100644 index 00000000..a794bc2d --- /dev/null +++ b/2023-01/spring-26/solution2/src/main/resources/templates/user.html @@ -0,0 +1,9 @@ + + + + + + +Доступ к USER + +