Примеры к занятию 21 (Spring Security вводное)

This commit is contained in:
kataus
2020-11-14 10:17:01 +03:00
parent f8e06dafe4
commit 97a5f80a31
16 changed files with 314 additions and 6 deletions
@@ -0,0 +1,21 @@
package ru.otus.spring.rest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.util.Optional;
@ControllerAdvice
public class SecurityAdvice {
private final Logger logger = LoggerFactory.getLogger( SecurityAdvice.class );
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleAnyError( Exception e ) {
logger.error( "some throuble", e );
return ResponseEntity.of( Optional.of( "Неудачник" ) );
}
}
@@ -29,6 +29,16 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
</dependencies>
<build>
@@ -6,10 +6,14 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ApplicationContext;
import org.springframework.retry.annotation.EnableRetry;
import ru.otus.spring.dto.Country;
import ru.otus.spring.service.CountryService;
import java.util.List;
@EnableCaching
@EnableRetry
@SpringBootApplication
public class Main {
@@ -22,5 +26,28 @@ public class Main {
Country country = service.getCountry("col");
log.info(country.getName());
country = service.getCountry("col");
log.info(country.getName());
country = service.getCountry("ru");
log.info(country.getName());
country = service.getCountry("col");
log.info(country.getName());
country = service.getCountry("ru");
log.info(country.getName());
service.getCountries();
country = service.getCountry("col");
log.info(country.getName());
}
}
@@ -10,6 +10,6 @@ public class CacheConfig {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("countiries");
return new ConcurrentMapCacheManager("countries");
}
}
@@ -7,6 +7,8 @@ public class Country {
private String name;
private String alpha3Code;
public String getName() {
return name;
}
@@ -14,4 +16,12 @@ public class Country {
public void setName(String name) {
this.name = name;
}
public String getAlpha3Code() {
return alpha3Code;
}
public void setAlpha3Code( String alpha3Code ) {
this.alpha3Code = alpha3Code;
}
}
@@ -2,8 +2,11 @@ package ru.otus.spring.service;
import ru.otus.spring.dto.Country;
import java.util.List;
public interface CountryService {
Country getCountry( String id );
List<Country> getCountries();
}
@@ -2,31 +2,54 @@ package ru.otus.spring.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestOperations;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import ru.otus.spring.dto.Country;
import java.net.URI;
import java.util.List;
@Service
public class CountryServiceRest implements CountryService {
private static final Logger log = LoggerFactory.getLogger(CountryServiceRest.class);
private static final Logger log = LoggerFactory.getLogger( CountryServiceRest.class );
private RestOperations rest = new RestTemplate();
// @Cacheable("countries")
@Retryable(value = Exception.class, maxAttempts = 5, backoff = @Backoff(delay = 5000))
@Override
public Country getCountry(String id) {
log.info("Request");
return rest.getForObject("http://restcountries.eu/rest/v2/alpha/" + id, Country.class);
public Country getCountry( String id ) {
log.info( "Request {}", id );
return rest.getForObject( "https://restcountries.eu/rest/v2/alpha/" + id
, Country.class );
}
@CacheEvict(cacheNames = {"countries"}, allEntries = true)
@Override
public List<Country> getCountries() {
RequestEntity request = new RequestEntity(new Country(), HttpMethod.GET
, UriComponentsBuilder.fromHttpUrl( "http://restcountries.eu" )
.path( "rest/v2/" )
.queryParam( "locale", "nl" )
.build().toUri() );
log.info( request.getUrl().toString() );
ResponseEntity<List<Country>> response
= rest.exchange( request,
new ParameterizedTypeReference<List<Country>>() {
} );
return response.getBody();
}
}
+53
View File
@@ -0,0 +1,53 @@
<?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-21-spring-security-start</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
</parent>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<java.version>11</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>
@@ -0,0 +1,12 @@
package ru.otus.spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class);
}
}
@@ -0,0 +1,32 @@
package ru.otus.spring.rest;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
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;
@Controller
public class PagesController {
@GetMapping("/")
public String indexPage() {
return "index";
}
@GetMapping("/public")
public String publicPage() {
return "public";
}
@GetMapping("/authenticated")
public String authenticatedPage() {
return "authenticated";
}
@GetMapping("/success")
public String successPage(){
return "success";
}
}
@@ -0,0 +1,78 @@
package ru.otus.spring.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import java.util.Collection;
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers("/")
.antMatchers( "/static/**" );
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
// По умолчанию SecurityContext хранится в сессии. Эта часть вырубает и каждый запросом приходитТ
// .sessionManagement()
// .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
// .and()
.authorizeRequests()
.antMatchers("/public/").anonymous()
.and()
.authorizeRequests()
.antMatchers("/authenticated").authenticated()
// .and()
// .authorizeRequests().antMatchers("/public").authenticated()
.and()
.httpBasic()
.and()
.anonymous()
.principal( "anonymous" )
.and()
.rememberMe().key( "Some secret" )
;
}
@Bean
public PasswordEncoder passwordEncoder() {
// return new BCryptPasswordEncoder(10);
return NoOpPasswordEncoder.getInstance();
// return new PasswordEncoder() {
// @Override
// public String encode(CharSequence charSequence) {
// return charSequence.toString();
// }
//
// @Override
// public boolean matches(CharSequence charSequence, String s) {
// return charSequence.toString().equals(s);
// }
// };
}
@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("password").roles("ADMIN")
;
}
}
@@ -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" 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>
</body>
</html>
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
</head>
<body>
Доступен всем
</body>
</html>
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Вы успешно вошли</title>
</head>
<body>
Вы успешно вошли
</body>
</html>