mirror of
https://github.com/OtusTeam/Spring.git
synced 2026-05-30 10:50:42 +00:00
Примеры к занятию Spring Security Авторизация для 2023-01.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>ru.otus</groupId>
|
||||
<artifactId>spring-framework-27-webflux</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.8</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>de.flapdoodle.embed</groupId>
|
||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>http://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
||||
@@ -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<ServerResponse> staticResourceRouter() {
|
||||
return RouterFunctions.resources( "/**.html", new ClassPathResource( "static/" ) );
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<Person, String> {
|
||||
|
||||
Mono<Person> findByName( String string );
|
||||
}
|
||||
@@ -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<Person> getAll() {
|
||||
return personRepository.findAll();
|
||||
}
|
||||
|
||||
@GetMapping("/person/find")
|
||||
public Mono<Person> find( @RequestParam("name") String name ) {
|
||||
return personRepository.findByName( name )
|
||||
.cache();
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/person")
|
||||
public Mono<Person> savePerson( @RequestBody Person person ) {
|
||||
return personRepository.save( person );
|
||||
}
|
||||
}
|
||||
+47
@@ -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 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
spring.mongodb.embedded.version: 3.5.5
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Только для авторизованных
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<a href="public.html">/public.html</a>
|
||||
<br>
|
||||
<a href="authenticated.html">/authenticated.html</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Доступен всем
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>ru.otus</groupId>
|
||||
<artifactId>classwork</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.8</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
+13
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -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";
|
||||
}
|
||||
}
|
||||
+16
@@ -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<String> accessError() {
|
||||
return ResponseEntity.of(Optional.of("Неудачник"));
|
||||
}
|
||||
}
|
||||
+10
@@ -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 {
|
||||
}
|
||||
+45
@@ -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<UserDetails>();
|
||||
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 );
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Страница с доступом только админу
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Только для аторизованных
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Вам доступ запрещён!
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<a th:href="@{public}">/public</a>
|
||||
<br>
|
||||
<a th:href="@{authenticated}">/authenticated</a>
|
||||
<br>
|
||||
<a th:href="@{user}">/user</a>
|
||||
<br>
|
||||
<a th:href="@{admin}">/admin</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Доступ к MANAGER
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Доступен всем
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Вы успешно вошли !
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Доступ к USER
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>ru.otus</groupId>
|
||||
<artifactId>spring-framework-27-oauth</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.6.10</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<ehcache-core.version>2.6.11</ehcache-core.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-ui</artifactId>
|
||||
<version>1.6.9</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>jquery</artifactId>
|
||||
<version>3.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>bootstrap</artifactId>
|
||||
<version>4.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>webjars-locator-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>js-cookie</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -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";
|
||||
}
|
||||
}
|
||||
+17
@@ -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<String, Object> user( @AuthenticationPrincipal OAuth2User principal) {
|
||||
return Collections.singletonMap("name", principal.getAttribute("name"));
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
spring:
|
||||
security:
|
||||
oauth2:
|
||||
client:
|
||||
registration:
|
||||
github:
|
||||
clientId: fdec09b924be7f214eaa
|
||||
clientSecret: 5436beb72dc2ec7f2320afcab5185c1ea03d484b
|
||||
|
||||
logging:
|
||||
level:
|
||||
root: error
|
||||
org.springframework.security: DEBUG
|
||||
@@ -0,0 +1,18 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<title>Demo</title>
|
||||
<meta name="description" content=""/>
|
||||
<meta name="viewport" content="width=device-width"/>
|
||||
<base href="/"/>
|
||||
<link rel="stylesheet" type="text/css" href="/webjars/bootstrap/css/bootstrap.min.css"/>
|
||||
<script type="text/javascript" src="/webjars/jquery/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="/webjars/bootstrap/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Demo</h1>
|
||||
<div class="container"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>ru.otus</groupId>
|
||||
<artifactId>solution2</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.8</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
+13
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+56
@@ -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";
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package ru.otus.spring.security;
|
||||
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
public class MethodSecurityConfiguration {
|
||||
}
|
||||
+51
@@ -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<UserDetails>();
|
||||
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 );
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Страница с доступом только админу
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Только для аторизованных
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Вам доступ запрещён!
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
<a th:href="@{public}">/public</a>
|
||||
<br>
|
||||
<a th:href="@{authenticated}">/authenticated</a>
|
||||
<br>
|
||||
<a th:href="@{user}">/user</a>
|
||||
<br>
|
||||
<a th:href="@{manager}">/manager</a>
|
||||
<br>
|
||||
<a th:href="@{admin}">/admin</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Доступ к MANAGER
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Доступен всем
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Вы успешно вошли !
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
Доступ к USER
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user