SlideShare uma empresa Scribd logo
1 de 192
Workshop Microservices
Microservices com Spring Cloud e
Netflix OSS
Objetivos
• Ao final desta unidade você compreenderá como:
• Compreender as funcionalidades das plataformas Spring Cloud e
Netflix OSS
• Implementar um serviço de configuração centralizada utilizando Spring
Cloud Config
• Realizar o registro e descoberta dos serviços utilizando Netflix Eureka
• Suportar tolerância à falhas e balanceamento de carga na chamada
entre serviços com Netflix Ribbon
• Tornar os serviços mais resilientes com a implementação de circuit
breakers com Netflix Hystrix
• Orquestrar a implementação de segurança entre serviços com Spring
Cloud Security
• Implementar um serviço de proxy e/ou roteamento utilizando Netflix
Zuul
Agenda
• Spring Cloud e Netflix OSS
• Spring Cloud Config
• Netflix Eureka
• Netflix Ribbon e Feign
• Netflix Hystrix
• Spring Cloud Security
• Netflix Zuul
Arquitetura Microservices
Microservices
• Quais os principais desafios?
• Gerenciamento de configuração
• Registro e descoberta dos serviços
• Roteamento
• Balanceamento de carga
• Tolerância à falhas
• Eureka
• Hystrix
• Ribbon
• Zuul
• + muitos outros…
• API
• Routing / Health check
• Microservices
• Logging
• Data Management
Spring Cloud
• Conjunto de bibliotecas / componentes
• Não é apenas uma ferramenta
• Integrado ao Spring Boot
• Suporta diferentes arquiteturas e tecnologias em Cloud
• AWS, Netflix, Heroku, Cloud Foundry, etc
• Facilita a implementação de padrões necessários aos
sistemas distribuídos
“Toolset designed for building distributed systems”
Spring Cloud
• Principais Componentes
Spring Cloud
Spring Cloud
Component Camden.SR7 Dalston.RELEASE
spring-cloud-aws 1.1.4.RELEASE 1.2.0.RELEASE
spring-cloud-bus 1.2.2.RELEASE 1.3.0.RELEASE
spring-cloud-cli 1.2.4.RELEASE 1.3.1.RELEASE
spring-cloud-commons 1.1.9.RELEASE 1.3.0.RELEASE
spring-cloud-contract 1.0.5.RELEASE 1.1.0.RELEASE
spring-cloud-config 1.2.3.RELEASE 1.3.0.RELEASE
spring-cloud-netflix 1.2.7.RELEASE 1.3.0.RELEASE
spring-cloud-security 1.1.4.RELEASE 1.2.0.RELEASE
spring-cloud-cloudfoundry 1.0.1.RELEASE 1.1.0.RELEASE
spring-cloud-consul 1.1.4.RELEASE 1.2.0.RELEASE
spring-cloud-sleuth 1.1.3.RELEASE 1.2.0.RELEASE
spring-cloud-stream Brooklyn.SR3 Chelsea.SR1
spring-cloud-zookeeper 1.0.4.RELEASE 1.1.0.RELEASE
spring-boot 1.4.5.RELEASE 1.5.2.RELEASE
spring-cloud-task 1.0.3.RELEASE 1.1.3.RELEASE
Spring Cloud
• Para adicionar no projeto basta incluir parent POM
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Spring Cloud + Netflix OSS
"Casamento perfeito para criação de
microservices auto-curáveis"
Gerenciamento de configuração Spring Cloud Config + Bus
Descoberta de serviços Netflix Eureka
Balanceamento de carga Netflix Ribbon
Tolerância à falhas Netflix Hystrix + Turbine
Roteamento Netflix Zuul
Segurança Spring Cloud Security
Spring Cloud + Netflix OSS
Gerenciamento de Configuração
Spring Cloud Config
“Gerenciamento de configuração para micro-serviços“
• Centraliza a configuração da aplicação
• Permite atualizações dinâmicas
• Suporta versionamento
• Suporte à rollback
• Suporta configuração via repositórios
• Git, SVN, filesystem
• Permite atualização via barramento
• Spring Cloud Bus
Spring Cloud Config
• Serviço de configuração centralizado
Spring Cloud Config (server)
• Basta adicionar a dependência Maven
• Utilizar a anotação @EnableConfigServer
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
@EnableConfigServer
@SpringBootApplication
public class ConfigServer {
public static void main(String[] args) {
SpringApplication.run(ConfigServer.class, args);
}
}
Spring Cloud Config (server)
• É necessário também configurar o repositório com as
configurações externas
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: file://config-repo
$ cd $HOME
$ mkdir config-repo
$ cd config-repo
$ git init .
$ echo foo > application.properties
$ git add -A .
$ git commit -m “Initial commit"
Spring Cloud Config (server)
@SpringBootApplication
@EnableConfigServer
public class ConfigServer {...}
spring.cloud.config.git.uri: https://github.com/...
ConfigServer.java
application.yml
Spring Cloud Config (server)
• É possível customizar configurações para utilização do
repositório Git
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
username: trolley
password: strongpassword
default-label: master
force-pull: true
basedir: file://server/local/path
timeout: 60
clone-on-start: true
search-paths: foo,bar*
Spring Cloud Config (server)
• Suporta também utilização de diferentes repositórios Git
de acordo com um padrão / perfil definido (12-factor)
spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo
repos:
development:
pattern:
- */development
- */staging
uri: https://github.com/development/config-repo
staging:
pattern:
- */qa
- */production
uri: https://github.com/staging/config-repo
Spring Cloud Config (server)
• Exemplo com configuração para SVN repo
• Exemplo com configuração para Filesystem
spring:
profiles:
active: subversion
cloud:
config:
server:
svn:
uri: https://svn/config-repo
default-label: trunk
spring:
profiles:
active: native
cloud:
config:
server:
native:
searchLocations: file://local/config-repo
Spring Cloud Config (server)
• Suporta a manipulação de diferentes Spring Profiles
• Basta acessar as configurações via HTTP REST no seguinte formato
• /{application}/{profile}[/{label}]
• /{application}-{profile}.yml
• /{label}/{application}-{profile}.yml
• /{application}-{profile}.properties
• /{label}/{application}-{profile}.properties
• YML
• Você configura dentro do próprio arquivo
• Separando por ---
• Properties
• application.properties
• application-dev.properties
• application-prod.properties
logging:
level: debug
---
spring:
profiles: dev, prod
logging:
level: info
application.yml
Spring Cloud Config (client)
Spring Cloud Config (client)
• Basta adicionar a dependência Maven
• Configurar o arquivo bootstrap.yml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
spring:
application:
name: microservice1
cloud:
config:
uri: http://localhost:8888
Spring Cloud Config (client)
@RefreshScope
@Component
public class AppComponent {
@Value("${thread-pool}")
private int threadPool;
@Value("${email}")
private String email;
@Autowired Environment env
}
• É possível buscar as propriedades definidas pelo Config Server
utilizando @Value e Spring Environment
• Existe a possibilidade de atualizar as propriedades sem
derrubar a aplicação, utilizando a anotação @RefreshScope
• POST http://localhost:8080/refresh
Laboratório 1 (cloud-lab01)
• Centralizando a configuração com Spring Cloud
Config
Spring Cloud Config + Bus
• Exemplo da arquitetura de replicação de configuração
utilizada
Spring Cloud Config + Bus
• Lightweight AMQP Messaging Broker
• Arquitetura flexível e fornece extensões para outros protocolos
• HTTP, STOMP, MQTT
• Ótima integração com Spring
• Spring Boot, Cloud Bus, Cloud Stream, Messaging
• Instalação
• Windows
• https://www.rabbitmq.com/install-windows.html
• Mac OS X
• brew install rabbitmq
• Linux
• apt-get install rabbitmq-server
• yum install rabbitmq-server
• Web Console
• http://localhost:15672
• user: guest / password: guest
RabbitMQ
Spring Cloud Config + Bus (server)
• É necessário adicionar as seguintes dependências
• É suportado também a utilização de Kafka ou Redis
como implementação do barramento
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-monitor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
spring:
cloud:
bus:
enabled: true
rabbitmq:
host: localhost
port: 5672
• Deve ser ativado o suporte ao
barramento via properties
Spring Cloud Config + Bus (client)
• É necessário adicionar as seguintes dependências
• Incorporar a seguinte configuração no bootstrap.yml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
spring:
application:
name: microservice1
cloud:
config:
uri: http://localhost:8888
rabbitmq:
host: localhost
port: 5672
Spring Cloud Config + Bus
• Configuração do Webhook no repositório Git
Laboratório 2 (cloud-lab02)
• Replicando a configuração centralizada com
Spring Cloud Config Bus
Registro e Descoberta de Serviços
Registro e Descoberta de Serviços
Registro e Descoberta de Serviços
Registro e Descoberta de Serviços
Service Register Health Check
Netflix Eureka
"Transparência de localização aos micro-serviços“
• Registro de serviços REST based
• Suporte à replicação
• Cache aplicado no stub cliente
• Resiliente
• Rápido… mas não consistente
• Fornece o alicerce para outros serviços
• Mantém registro de clientes com metadados
Netflix Eureka (server)
• Basta adicionar a dependência Maven
• Utilizar a anotação @EnableEurekaServer
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class, args);
}
}
Netflix Eureka (server)
• Exemplo de configuração básica application.yml
• Para acessar o Eureka Dashboard Web
• http://localhost:8761
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
Netflix Eureka (server)
Netflix Eureka
@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {...}
EurekaServer.java
Netflix Eureka (client)
• Basta adicionar a dependência Maven
• Utilizar a anotação @EnableDiscoveryClient
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClient {
public static void main(String[] args) {
SpringApplication.run(EurekaClient.class, args);
}
}
Netflix Eureka (client)
• Exemplo de configuração básica application.yml
• Cliente será registrado no Eureka Server
spring:
application:
name: spring-cloud-eureka-client
eureka:
client:
serviceUrl:
defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
instance:
preferIpAddress: true
Netflix Eureka (client)
• Exemplo utilizando DiscoveryClient
@RestController
public class ProductController {
@Autowired DiscoveryClient discoveryClient;
@GetMapping("/get/customers")
public void getCustomers() throws Exception {
List<ServiceInstance> instances =
discoveryClient.getInstances("customer-service");
ServiceInstance firstOne = instances.get(0);
String uri = "http://" + firstOne.getHost() + ":" +
firstOne.getPort();
HttpGet getRequest = new HttpGet(uri + "/customers");
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(getRequest);
// ...
}
}
Netflix Eureka (client)
• Exemplo utilizando RestTemplate
@RestController
public class ProductController {
@Autowired RestTemplate restTemplate;
@GetMapping("/get/customers")
public void getCustomers() throws Exception {
// use the "smart" Eureka-aware RestTemplate
ResponseEntity<List<CustomerDTO>> exchange =
this.restTemplate.exchange(
"http://customer-service/customers",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<CustomerDTO>>() {},
(Object) null);
// ...
}
}
Laboratório 3 (cloud-lab03)
• Registrando e descobrindo serviços com Netflix
Eureka
Netflix Eureka
Netflix Eureka
Netflix Eureka
• Para configurar o mecanismo de suporte à replicação
---
spring:
profiles: peer1
eureka:
instance:
hostname: peer1
client:
serviceUrl:
defaultZone: http://peer2:[port]/eureka/
---
spring:
profiles: peer2
eureka:
instance:
hostname: peer2
client:
serviceUrl:
defaultZone: http://peer1:[port]/eureka/
## Hosts / IPs
peer1 127.0.0.1
peer2 127.0.0.1
/etc/hosts
application.yml
Netflix Eureka
Laboratório 4 (cloud-lab04)
• Ativando o suporte à replicação com Netflix
Eureka
Balanceamento de Carga
Balanceamento de Carga
Netflix Ribbon
"Balanceamento de carga para microservices"
• Balanceamento decentralizado no cliente
• Resiliente
• Suporte à tolerância a falhas
• Trabalha com múltiplos protocolos
• HTTP, TCP, UDP
• Modelo assíncrono e reativo
• Suporte à caching e batching
• Múltiplos algoritmos de balanceamento
Netflix Ribbon
Netflix Ribbon
• Basta adicionar a dependência Maven
• Pode ser utilizado de duas maneiras
• Diretamente (sem Eureka)
• Por meio do objeto LoadBalancerClient
• Utilizando configurações na aplicação
• Properties, Ribbon Client Configuration
• Por meio de anotações
• @RibbonClient, @LoadBalanced
• Integrado (com Eureka)
• Pode ser customizado via propriedades
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
Netflix Ribbon
• Exemplo de configuração do Ribbon client
public class GroupRibbonConfiguration {
@Autowired IClientConfig ribbonClientConfig;
@Bean
public IPing ribbonPing(IClientConfig config) {
return new PingUrl();
}
@Bean
public IRule ribbonRule(IClientConfig config) {
return new AvailabilityFilteringRule();
}
} group-service:
ribbon:
eureka:
enabled: false
listOfServers: localhost:9092,localhost:9999
ServerListRefreshInterval: 15000
Netflix Ribbon
• Configurações possíveis para Ribbon Configuration
• IClientConfig
• Define a configuração para o cliente do load balancer
• ServerList<Server>
• Define como recuperar a lista de servidores para escolha
• ServerListFilter<Server>
• Define uma lista de filtro para a lista de servidores para escolha
• ILoanBalancer
• Representa o software de load balancer
• IRule
• Descreve a estratégia de load balancing
• IPing
• Define qual a periodicidade dos pings realizados
Netflix Ribbon
• Configurações possíveis para IRule
• AvailabilityFilteringRule
• ClientConfigEnabledRoundRobinRule
• RandomRule
• ResponseTimeWeightedRule
• RetryRule
• RoundRobinRule
• WeightedResponseTimeRule
• ZoneAvoidanceRule
Netflix Ribbon
• Configurações possíveis para ILoadBalancer
• BaseLoadBalancer
• DynamicServerListLoadBalancer
• NoOpLoadBalancer
• ZoneAwareLoadBalancer
• Configurações possíveis para IPing
• DummyPing
• NoOpPing
• PingConstant
Netflix Ribbon
• Uso direto via LoadBalancerClient
@RestController
@RibbonClient(name = "group-service",
configuration = GroupRibbonConfiguration.class)
public class UserController {
@Autowired
LoadBalancerClient loadBalancer;
@RequestMapping("/users/{id}/group")
public Group userGroup(@PathVariable Long id) {
ServiceInstance instance = loadBalancer.choose("group-service");
URI storesUri = URI.create(String.format(“http://%s:%s",
instance.getHost(), instance.getPort()));
// ... do something with the URI
}
}
Netflix Ribbon
• Uso direto via @LoadBalanced
@RestController
@RibbonClient(name = "group-service",
configuration = GroupRibbonConfiguration.class)
public class UserController {
@LoadBalanced @Bean
RestTemplate restTemplate(){
return new RestTemplate();
}
@Autowired RestTemplate restTemplate;
@RequestMapping("/users/{id}/group")
public Group userGroup(@PathVariable Long id) {
return this.restTemplate.getForObject(
"http://group-service/user/" + id, Group.class);
}
}
Netflix Ribbon
@EnableDiscoveryClient
@SpringBootApplication
public class RibbonEurekaClient {
public static void main(String[] args) {
SpringApplication.run(RibbonEurekaClient.class, args);
}
}
spring:
application:
name: ribbon-client
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka
instance:
preferIpAddress: true
• Exemplo de uso com Eureka
Netflix Ribbon
• Exemplo de uso com Eureka
• group-service é um serviço registrado no Eureka
@RestController
public class UserController {
@LoadBalanced @Bean
RestTemplate restTemplate(){
return new RestTemplate();
}
@Autowired RestTemplate restTemplate;
@RequestMapping("/users/{id}/group")
public Group userGroup(@PathVariable Long id) {
return this.restTemplate.getForObject(
"http://group-service/user/" + id, Group.class);
}
}
Laboratório 5 (cloud-lab05)
• Implementando balanceamento de carga e
tolerância à falhas com Netflix Ribbon
Netflix Feign
• Facilita criação de clientes REST
• Ótima integração com Spring Cloud
• Suporta implementação de circuit breakers
• Simples, produtivo e customizável
• Pode ser utilizado em conjunto com
• Ribbon - balanceamento de carga
• Eureka - descoberta dos serviços
“Declarative REST interfaces"
Netflix Feign
• Basta adicionar a dependência Maven
• Utilizar a anotação @EnableFeignClients
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
@EnableFeignClients
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Netflix Feign
• Exemplo de uso com Eureka (service-id)
• Utilização com URL externas
@FeignClient("stores-service")
public interface StoreClient {
@RequestMapping(method = RequestMethod.GET, value = "/stores")
List<Store> getStores();
@RequestMapping(method = RequestMethod.POST,
value = "/stores/{storeId}", consumes = "application/json")
Store update(@PathVariable("storeId") Long storeId, Store store);
}
@FeignClient(name = "stores-service", url = "http://example.com")
public interface StoreClient {}
Netflix Feign
• Exemplo de customização de configurações
@Configuration
public class CustomFeignConfiguration {
static final int FIVE_SECONDS = 5000;
@Bean
public Logger.Level feignLogger() {
return Logger.Level.FULL;
}
@Bean
public Request.Options options() {
return new Request.Options(FIVE_SECONDS, FIVE_SECONDS);
}
}
@FeignClient(value = "stores-service",
configuration = CustomFeignConfiguration.class)
public interface StoreClient {...}
Netflix Feign
• Configurações opcionais
• Decoder: decodificação do response payload
• Encoder: codificação do request payload
• Logger: definição da engine de logging
• Contract: configuração para utilizando Spring Cloud Contract
• Feign.Builder: customização do Builder Feign
• Logger.Level: definição do nível de logging
• Retryer: estratégia para implementação de retry
• ErrorDecoder: decodificação para erros no response
• Request.Options: opções para customização das requisições
Netflix Feign
• Oferece suporte à compressão do request e response
• Funcionamento similar as configurações fornecidas pelo
Web server
• Ótimo para melhoria de performance em requisições e
respostas com muitos dados envolvidos
feign.compression.request.enabled=true
feign.compression.response.enabled=true
feign.compression.request.mime-types=application/xml,application/json
feign.compression.request.min-request-size=2048
Netflix Feign
• Oferece customização para mecanismo logging
• Pode ser definido logging por Feign client definido
• Ou pode ser alterado o nível de log padrão Logger.Level
• NONE: Nenhuma impressão de log
• BASIC: Apenas dos métodos de request, URL, e status de respostas
• HEADERS: Informação básica sobre headers do request / response
• FULL: Headers, body, e metadados das requisições e respostas
logging.level.project.user.UserClient: DEBUG
@Configuration
public class FooConfiguration {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
Netflix Feign
• Oferece também uma Feign Client Builder API
public interface BookClient {
@RequestLine("GET /{isbn}")
BookResource findByIsbn(@Param("isbn") String isbn);
@RequestLine("GET")
List<BookResource> findAll();
@RequestLine("POST")
@Headers("Content-Type: application/json")
void create(Book book);
}
BookClient bookClient = Feign.builder()
.client(new OkHttpClient())
.encoder(new GsonEncoder())
.decoder(new GsonDecoder())
.logger(new Slf4jLogger(BookClient.class))
.logLevel(Logger.Level.FULL)
.target(BookClient.class, "http://localhost:8081/api/books");
Netflix Feign
• É possível customizar diferentes Enconder e Decoder
• GSON
• Jackson
• Sax
• JAXB
Feign.builder()
.encoder(new GsonEncoder())
.decoder(new GsonDecoder());
Feign.builder()
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder());
Feign.builder()
.decoder(SAXDecoder.builder()
.registerContentHandler(UserIdHandler.class)
.build());
Feign.builder()
.encoder(new JAXBEncoder())
.decoder(new JAXBDecoder());
Netflix Feign
• Outras configurações também são suportadas
• JAX-RS
• OkHttp
• SLF4J
Feign.builder().contract(new JAXRSContract());
Feign.builder().client(new OkHttpClient());
Feign.builder().logger(new Slf4jLogger());
interface GitHub {
@GET @Path("/repos/{owner}/{repo}/contributors")
List<Contributor> contributors(
@PathParam("owner") String owner,
@PathParam(“repo") String repo);
}
Netflix Feign
• Para trabalhar com Spring MultipartFile
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>2.1.0</version>
</dependency>
@Configuration
class MultipartSupportConfig {
@Bean
@Primary
@Scope("prototype")
Encoder feignFormEncoder() {
return new SpringFormEncoder();
}
}
@FeignClient(name = "file-upload-service",
configuration = MultipartSupportConfig.class)
interface ServiceClient {
@RequestMapping(method = RequestMethod.POST, value = "/upload")
ResponseEntity upload(@RequestPart(value="content") MultipartFile file)
}
Netflix Feign
• Sugestão de design para implementação nas aplicações
public interface UserService {
@RequestMapping(method = RequestMethod.GET, value ="/users/{id}")
User getUser(@PathVariable("id") long id);
}
@RestController
public class UserRestController implements UserService {
User getUser(@PathVariable("id") long id) {
// Implement the REST endpoint
}
}
@FeignClient("users")
public interface UserClient extends UserService {
// Empty
}
Laboratório 6 (cloud-lab06)
• Implementando clientes REST com Netflix Feign
Tolerância à Falhas
Tolerância à Falhas
Tolerância à Falhas
Netflix Hystrix
“Tolerância à falhas para micro-serviços“
• Implementa padrão circuit breakers
• Fornece monitoramento aos serviços
• Hystrix dashboard
• Suporta comandos assíncronos
• Utiliza diferentes thread pools
• Pode implementar timeouts
Netflix Hystrix
• Circuit Breaker Pattern
• Máquina de estados
• Closed, Open, Half-Open
• Falha não é propagada para
chamada do cliente
Netflix Hystrix
• Basta adicionar a dependência Maven
• Utilizar a anotação @EnableCircuitBreaker
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
@EnableCircuitBreaker
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
• Exemplo de implementação @HystrixCommand
Netflix Hystrix
public class StoreIntegration {
@HystrixCommand(fallbackMethod = "defaultStores")
public Object getStores(Map<String, Object> parameters) {
//do stuff that might fail
}
public Object defaultStores(Map<String, Object> parameters) {
return /* something useful */;
}
}
Netflix Hystrix
Netflix Hystrix
• Suporte integrado ao Feign via Hystrix Fallback
@FeignClient(name = "service-to-call", fallback = FeignClientFallback.class)
public interface FeignClient {
@RequestMapping(value = "/rest/do", method = RequestMethod.GET)
ResponseEntity<String> doSomething();
}
@Component
public class FeignClientFallback implements FeignClient {
@Override
public ResponseEntity<String> doSomething() {
return ResponseEntity.ok("fallback");
}
}
Netflix Hystrix
• Configurações possíveis para Hystrix Command
• Execution
• execution.isolation.strategy
• execution.isolation.thread.timeoutInMilliseconds
• execution.timeout.enabled
• execution.isolation.thread.interruptOnTimeout
• execution.isolation.thread.interruptOnCancel
• execution.isolation.semaphore.maxConcurrentRequests
• Fallback
• fallback.isolation.semaphore.maxConcurrentRequests
• fallback.enabled
https://github.com/Netflix/Hystrix/wiki/Configuration
Netflix Hystrix
• Configurações possíveis para Hystrix Command
• Circuit Breaker
• circuitBreaker.enabled
• circuitBreaker.requestVolumeThreshold
• circuitBreaker.sleepWindowInMilliseconds
• circuitBreaker.errorThresholdPercentage
• circuitBreaker.forceOpen
• circuitBreaker.forceClosed
• Request Context
• requestCache.enabled
• requestLog.enabled
https://github.com/Netflix/Hystrix/wiki/Configuration
Netflix Hystrix
• Configurações possíveis para Hystrix Command
• Metrics
• metrics.rollingStats.timeInMilliseconds
• metrics.rollingStats.numBuckets
• metrics.rollingPercentile.enabled
• metrics.rollingPercentile.timeInMilliseconds
• metrics.rollingPercentile.numBuckets
• metrics.rollingPercentile.bucketSize
• metrics.healthSnapshot.intervalInMilliseconds
https://github.com/Netflix/Hystrix/wiki/Configuration
Netflix Hystrix
• Outras possíveis configurações
• Collapser Properties
• maxRequestsInBatch
• timerDelayInMilliseconds
• requestCache.enabled
• Thread Pool
• coreSize
• maximumSize
• maxQueueSize
• queueSizeRejectionThreshold
• keepAliveTimeMinutes
• allowMaximumSizeToDivergeFromCoreSize
https://github.com/Netflix/Hystrix/wiki/Configuration
Netflix Hystrix
• Propriedades podem ser configuradas via anotação
• @HystrixCommand e @HystrixProperty
@HystrixCommand(fallbackMethod = "defaultStores",
commandProperties = {
@HystrixProperty(name="execution.isolation.strategy", value="THREAD"),
@HystrixProperty(name="requestCache.enabled", value="false")
},threadPoolProperties = {
@HystrixProperty(name="coreSize", value="5"),
@HystrixProperty(name="maximumSize", value="5")
})
public Object getStores(Map<String, Object> parameters) {
//do stuff that might fail
}
Netflix Hystrix
• Propriedades podem ser configuradas via YML
hystrix:
command:
FeignClient#doSomething():
execution:
isolation:
strategy: SEMAPHORE
semaphore:
maxConcurrentRequests: 5
fallback:
isolation:
semaphore:
maxConcurrentRequests: 5
circuitBreaker:
requestVolumeThreshold: 5
application.yml
Netflix Hystrix
• Estratégia de execução THREAD vs. SEMAPHORE
Laboratório 7 (cloud-lab07)
• Implementando circuit breakers com Netflix
Hystrix
Hystrix Dashboard
Hystrix Dashboard
• Basta adicionar a dependência Maven
• Utilizar a anotação @EnableHystrixDashboard
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
@EnableHystrixDashboard
@SpringBootApplication
public class HytrixDashboard {
public static void main(String[] args) {
SpringApplication.run(HytrixDashboard.class, args);
}
}
Hystrix Dashboard
• Para visualizar o dashboard basta acessar o endereço
• http://localhost:[port]/hystrix
Hystrix Dashboard
• Visualização do painel de circuitos para um serviço
Hystrix Dashboard
Netflix Turbine
• Agregador dos eventos Hystrix
Netflix Turbine
• Basta adicionar a dependência Maven
• Utilizar a anotação @EnableTurbine
• Pode ser utilizando em conjunto Hystrix Dashboard
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>
</dependency>
@EnableTurbine
@SpringBootApplication
public class TurbineApplication {
public static void main(String[] args) {
SpringApplication.run(TurbineApplication.class, args);
}
}
Netflix Turbine
• É necessário configurar um cluster para visualização dos
eventos gerados pelos serviços
• Utiliza o registro Eureka para localização dos serviços
• Basta adicionar uma configuração nas propriedades
• Pode ser definido diferentes configurações de clusters (views)
• http://turbine.sever/turbine.stream?cluster=<CLUSTERNAME>
turbine:
appConfig: service-a, service-b
clusterNameExpression: "'default'"
turbine:
aggregator:
clusterConfig: STORE
appConfig: customers,stores,ui,admin
Netflix Turbine
• Para acessar o endereço do Turbine no Hystrix Dashboard
• http://turbine.server:[port]/turbine.stream
• Agregador dos eventos Hystrix assíncrono
Netflix Turbine Stream
• Utiliza um sistema de mensagens assíncrono para
publicar e processar os eventos Hystrix
• Pode ser utilizado com diferentes middleware
• RabbitMQ, ActiveMQ, Apache Kafta, etc
• Cada serviço publica seus eventos na fila processada pelo
Turbine
Netflix Turbine Stream
Netflix Turbine Stream (server)
• Basta adicionar a dependência Maven
• É necessário também adicionar a dependência de um
Stream (Rabbit, Kafta, etc)
• spring-cloud-starter-stream-rabbit
• Utilizar a anotação @EnableTurbineStream
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine-stream</artifactId>
</dependency>
@EnableTurbineStream
@SpringBootApplication
public class TurbineStreamApplication {}
Netflix Turbine Stream (client)
• Necessário adicionar a dependência Hystrix stream
• Também necessário adicionar a dependência de um
Stream (Rabbit, Kafta, etc)
• spring-cloud-starter-stream-rabbit
• Caso necessário configurar as propriedades de
configuração no Stream adicionado
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix-stream</artifactId>
</dependency>
Laboratório 8 (cloud-lab08)
• Monitorando os circuitos com Hystrix Dashboard e
Turbine
Segurança
Closed ClosedOpen
Autenticação Autorização
Principais requisitos de segurança?
• Como identificar as permissões que serão manipuladas?
• Como a informação será codificada e decodificada?
• Quais dados serão necessários para restrição de acesso?
• Quem será responsável por armazenar e fornecer os dados de
segurança?
• Como identificar se a requisição não foi modificada?
“Stop bad guys from accessing your resources"
Segurança com REST
• Algumas estratégias para proteger os serviços
• Basic Auth (HTTP Basic)
• Network Security
• Certificate Based
• Arquitetura RESTful não define procedimentos de
segurança
• HTTP methods: GET, POST, PUT, DELETE
• API’s REST são tão vulneráveis quanto aplicações web
tradicionais
• SQL Injection, replay attacks, cross-site scripting, etc
HTTP Basic Auth
• Qual o problema com isto?
• Nada, mas…
• Em qual lugar você busca as credenciais?
• Ok para sistemas onde todos os participantes podem
compartilhar dados confidenciais de um modo seguro
• Apenas suporta informações de "usuário / senha”
• Apenas trabalha com autenticação
• Sem distinção entre usuários e máquinas
$ curl “https://$username:$password@myhost/resource"
Network Security
• Qual o problema com isto?
• Nada, mas…
• Chato para "debugar" e um pouco difícil de manter
• Configuração fica fora do escopo de desenvolvedores
• Não existe o conceito de identidade e autenticação
"Security architecture based on top of web server"
Certificate Based
• Qual o problema com isto?
• Nada, mas…
• Não existe o conceito de identidade, apenas caso o browser
tenha os certificados instalados
• Obriga keystores e certificados nas aplicações e nos serviços
• Não existe uma distinção muito clara quanto a usuários e
máquinas
$ curl -k -cert file.pem:password https://myhost:443/resource
OAuth 2.0
• Protocolo baseado em uma especificação de padrão
aberto definido pelo IETF
• Habilita as aplicações acessarem e compartilharem
serviços sem necessidade de compartilhar credenciais
• Evita problemas com "passwords"
• Essencial para mecanismo via delegação de acesso
• Aplicações terceiras
• Para serviços específicos
• Por um tempo limitado
• Pode trabalhar com revogação seletiva
Quem utiliza OAuth
OAuth Timeline
• OAuth 1.0
• Especificação core publicada em dezembro/2007
• OAuth 1.0a
• Especificação revisada publicada em junho/2009
• Relacionado a correções de vulnerabilidades de segurança
• OAuth 2.0
• Especificação publicada em outubro/2012
• Ser mais seguro, simples e padronizado
• RFCs adicionais ainda continuam sendo trabalhadas
OAuth 2.0 Tokens
• Tipos
• Bearer
• Large random token
• Necessita de SSL para proteção em transito
• Servidor necessita gerar e armazenar este hash
• Mac
• Utilizado para evitar repetição
• Não requer a utilização de SSL
• Apenas suportado no OAuth 1.0
• Access Token
• Short-lived token
• Refresh Token
• Long-lived token
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":“bearer",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
}
OAuth 2.0 Flow
OAuth 2.0 Flow
Papéis Envolvidos
• Resource Server
• Proteção dos serviços
• Authorization Server
• Emissão de tokens de acesso para os clientes
• Client Application
• Solicita os serviços protegidos em nome do proprietário
• Resource Owner
• Concede o acesso a um serviço protegido
OAuth 2.0 Grant Types
• Authorization Code (web apps)
• Confidencialidade aos clientes
• Utiliza um código de autorização emitido pelo servidor
• Implicit (browser-based and mobile apps)
• Script heavy web apps
• Usuário final pode ver o access token gerado
• Resource Owner Password Credentials (user / password)
• Utilizado em casos aonde o usuário confia no cliente
• Expõe as credenciais do usuário para o cliente
• Client Credentials (application)
• Clientes recebem um token (secret) para acesso
• Ideal para acesso entre aplicações
OAuth 2.0 Grant Types
• Authorization Code
http://server/oauth/authorize?response_type=code&client_id=client
&scope=read+write+trust
&redirect_uri=http://localhost/app
http://server/oauth/token?grant_type=authorization_code&code=SkiGJ8
&client_id=client
&client_secret=secret
&redirect_uri=http://localhost/app
{"access_token":"292e1ec1-fda9-4968-b1c3-7cc0dd99483f",
"token_type":"bearer",
"expires_in":299997,
"scope":"trust write read"}
OAuth 2.0 Grant Types
• Implicit
http://server/oauth/authorize?response_type=token&client_id=client
&scope=read+write+trust
&redirect_uri=http://localhost/app
http://localhost/app/#?access_token=292e1ec1-fda9-4968-
b1c3-7cc0dd99483f
OAuth 2.0 Grant Types
• Resource Owner Password Credentials
http://server/oauth/token?grant_type=password&client_id=client
&client_secret=secret
&username=admin
&password=admin
{"access_token":"292e1ec1-fda9-4968-b1c3-7cc0dd99483f",
"token_type":"bearer",
"expires_in":299997,
"scope":"trust write read"}
OAuth 2.0 Grant Types
• Client Credentials
http://server/oauth/token?grant_type=client_credentials
&client_id=client&client_secret=secret
{"access_token":"292e1ec1-fda9-4968-b1c3-7cc0dd99483f",
"token_type":"bearer",
"expires_in":299997,
"scope":"trust write read"}
OAuth 2.0 Prós & Contras
• Prós
• Ótima integração para acesso de aplicações à serviços oferecidos
por web sites
• Acesso permitido para um escopo limitado ou por tempo (duração)
• Sem necessidade de compartilhamento de passwords com
aplicações terceiras
• Contras
• Implementação pode ser um pouco complexa
• Problemas de interoperabilidade
• Algumas más implementações podem expor falhas de segurança
Spring Security OAuth
• Oferece implementação para OAuth (1a) e OAuth2
• Implementa os 4 tipos de authorization grants
• Suporta todos os requisitos definidos pelo OAuth2
• Authorization Server
• Resources Server
• Client
• Ótima integração com Spring MVC e JAX-RS
• Configuração utilizando anotações
• Integração com todo o eco-sistema Spring
Spring Authorization Server
• @EnableAuthorizationServer
• Anotação utilizada para configurar OAuth2 authorization server
• Existe também disponível em XML <authorization-server/>
• ClientDetailsServiceConfigurer
• Define os detalhes do cliente do serviço
• Implementação in-memory ou via JDBC
• AuthorizationServerTokenServices
• Operações para gerenciar OAuth2 tokens
• Tokens in-memory, JDBC ou JSON Web Token (JWT)
• AuthorizationServerEndpointConfigurer
• Fornece os grant types suportado pelo servidor
• Todos os grant types são suportados exceto via password
Spring Resource Server
• Pode ser a mesma instância do Authorization Server
• Ou então instalado como uma aplicação separada
• Fornece um filtro de autenticação para aplicações web
• @EnableResourceServer
• Anotação utilizada para configurar OAuth2 resource server
• Existe também disponível em XML <resource-server/>
• Suporta controle de acesso via expressions
• #oauth2.hasScope
• #oauth2.clientHasRole
• #oauth2.clientHasAnyRole
• #oauth2.denyClient
Spring OAuth2 Client
• Cria um filtro para armazenar o contexto do request
• Gerencia o redirecionamento de/para o servidor de
autenticação OAuth2
• @EnableOAuth2Client
• Anotação utilizada para configurar o OAuth2 client
• Existe também disponível em XML <client/>
• OAuth2RestTemplate
• Wrapper client object para acessar os serviços
Authorization Server
@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(
AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess(“permitAll()”)
.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(
ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("SampleClientId")
.secret("secret")
.authorizedGrantTypes("authorization_code")
.scopes("user_info")
.autoApprove(true) ;
}
}
Resource Server
@Configuration
@EnableResourceServer
public class ResourceServerConfig
extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/users/ping").permitAll()
.antMatchers("/users/current").authenticated()
.anyRequest().authenticated();
}
}
Laboratório 9 (cloud-lab09)
• Implementando e manipulando segurança com o
protocolo OAuth2
JSON Web Token
“Padrão aberto que define uma forma compacta e
auto-contida para transmitir de forma segura,
informações entre duas partes“
JSON Web Token
• Basta adicionar a dependência Maven
• Definir um JwtTokenStore
• Configurar um JwtAccessTokenConverter
• Utilizando chaves simétricas, ou assimétricas
• Configurar o modelo geração e validação de JWT tokens
nos serviços de autorização e recursos OAuth2
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
</dependency>
JSON Web Token
• Configuração utilizando modelo simétrico de chaves
@Configuration
public class JwtConfig {
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter =
new JwtAccessTokenConverter();
converter.setSigningKey("123");
return converter;
}
}
JSON Web Token
• Modelo assimétrico de chaves (chave privada)
@Configuration
public class JwtConfig {
//...
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter =
new JwtAccessTokenConverter();
KeyStoreKeyFactory keyStoreKeyFactory =
new KeyStoreKeyFactory(new ClassPathResource(“mykeys.jks"),
"mypass".toCharArray());
converter.setKeyPair(
keyStoreKeyFactory.getKeyPair("security-server"));
return converter;
}
}
JSON Web Token
• Modelo assimétrico de chaves (chave pública)
@Configuration
public class JwtConfig {
//...
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter =
new JwtAccessTokenConverter();
Resource resource = new ClassPathResource("public.txt");
String publicKey = null;
try {
publicKey = IOUtils.toString(resource.getInputStream());
} catch (final IOException e) {
throw new RuntimeException(e);
}
converter.setVerifierKey(publicKey);
return converter;
}
}
JSON Web Token
• Para realizar a geração do par de chaves (privada e pública) pode
ser utilizado keytool
• Para exportar a chave pública, pode ser utilizado openssl
keytool -genkeypair -alias mytest -keyalg RSA -keypass mypass
-keystore mytest.jks -storepass mypass
keytool -list -rfc --keystore mytest.jks | openssl x509 -inform pem -pubkey
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgIK2Wt4x2EtDl41C7vfp
OsMquZMyOyteO2RsVeMLF/hXIeYvicKr0SQzVkodHEBCMiGXQDz5prijTq3RHPy2
/5WJBCYq7yHgTLvspMy6sivXN7NdYE7I5pXo/KHk4nz+Fa6P3L8+L90E/3qwf6j3
DKWnAgJFRY8AbSYXt1d5ELiIG1/gEqzC0fZmNhhfrBtxwWXrlpUDT0Kfvf0QVmPR
xxCLXT+tEe1seWGEqeOLL5vXRLqmzZcBe1RZ9kQQm43+a9Qn5icSRnDfTAesQ3Cr
lAWJKl2kcWU1HwJqw+dZRSZ1X4kEXNMyzPdPBbGmU6MHdhpywI7SKZT7mX4BDnUK
eQIDAQAB
-----END PUBLIC KEY-----
JWT Response
• Exemplo de resposta utilizando JWT
{
"access_token":
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTMyODMxNzksInVzZXJfbmFtZSI6
InVzZXIiLCJhdXRob3JpdGllcyI6WyJVU0VSIiwiTUFOQUdFUiJdLCJqdGkiOiJkMGY5OTY2OC01Nz
dkLTRkZTEtODkwYi1hNDY1MTBkZjg2YjAiLCJjbGllbnRfaWQiOiJjbGllbnQiLCJzY29wZSI6WyJv
cGVuaWQiXX0.iH1pnwJZPZi05hdpY9MDGIvtx34Dj8lxc5fdU5c5NCCtUblT_L9kdZO6NaOIIZffbG
zSHoyVUEZkSwkGXm6lT1jRTcOHq2khAZlwmO3hN3c1xb8bumAgmpF8fJSIKTVIkFJpbVO4uDfHSSbB
m6QsTbqHkNgNwWSWbNG1n6ZlsHCcZCh37cmgbh-
B4tPD9QEfH3CSI6Z7AgUbS9UCIytjm02sgxgAr3liOcykRrdcOvxgIBx_yGDvornQ5JOBVdW-TS0-
uJmHe6sHCFYeBNchJhRi7xqZCMYFD6IcP4dftPupzg3IMl5oWberxhZTCCLoi18JtQyZgIgqmSlOAI
q8wg",
"token_type": "bearer",
"expires_in": 43199,
"scope": "openid",
"jti": "d0f99668-577d-4de1-890b-a46510df86b0"
}
JWT Response
• É possível informações extras no JWT gerado
implementando customizações via TokenEnhancer
public class CustomTokenEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken,
OAuth2Authentication authentication) {
Map<String, Object> additionalInfo = new HashMap<>();
additionalInfo.put("organization",
authentication.getName() + randomAlphabetic(4));
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(
additionalInfo);
return accessToken;
}
}
JWT Response
• Exemplo de payload com informações extras adicionadas
via TokenEnhancer
{
"user_name": "john",
"scope": [
"foo",
"read",
"write"
],
"organization": "johnIiCh",
"exp": 1458126622,
"authorities": [
"ROLE_USER"
],
"jti": "e0ad1ef3-a8a5-4eef-998d-00b26bc2c53f",
"client_id": "fooClientIdPassword"
}
Laboratório 10 (cloud-lab10)
• Trabalhando com JSON Web Tokens
Spring Cloud Security
“Segurança aplicada para microservices"
• Integração com Spring Security + OAuth2
• Proteção dos serviços com tokens (JWT)
• SSO com OAuth2 e OpenID Connect
• Transmissão tokens entre SSO e apps
• OAuth2 + JWT + SSO ;)
Spring Cloud Security
Discovery	
Client
Relying Party
Resource
Server
Get an access token
& an ID Token (JWT)
Use an access token
Authorization
Server
Iden.ty	Provider	or	
IDP	or		
OpenID	Provider	or	
OP	
	
	
Authorization
Endpoint
Token
Endpoint
Important Stuff
Userinfo
Endpoint
Registration
Endpoint
JWKS
Endpoint
JWKS
Endpoint
Validate
(JWT)
ID Token
/.well-known	
/webfinger	
/openid-configura.on
Check Session IFrame
End Session Endpoint
Spring Cloud Security
• Basta adicionar a seguinte dependência Maven
• Integração dos projetos Spring Security OAuth2 + JWT
• spring-security-oauth2 e spring-security-jwt
• Customizações de segurança as projetos Spring Cloud
• OAuth2FeignRequestInterceptor
• OAuth2LoadBalancerClientAutoConfiguration
• AccessTokenContextRelay
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
Spring Cloud Security
• Propriedades customizadas para integração com serviço
de recursos OAuth2
# SECURITY OAUTH2 RESOURCES (ResourceServerProperties)
security.oauth2.resource.filter-order= # The order of the filter chain used to
authenticate tokens.
security.oauth2.resource.id= # Identifier of the resource.
security.oauth2.resource.jwt.key-uri= # The URI of the JWT token. Can be set if
the value is not available and the key is public.
security.oauth2.resource.jwt.key-value= # The verification key of the JWT token.
Can either be a symmetric secret or PEM-encoded RSA public key.
security.oauth2.resource.prefer-token-info=true # Use the token info, can be set
to false to use the user info.
security.oauth2.resource.service-id=resource #
security.oauth2.resource.token-info-uri= # URI of the token decoding endpoint.
security.oauth2.resource.token-type= # The token type to send when using the
userInfoUri.
security.oauth2.resource.user-info-uri= # URI of the user endpoint.
Spring Cloud Security
• Propriedades customizadas para um cliente OAuth2
• PPro
• Propriedades customizadas para trabalhar com SSO
# SECURITY OAUTH2 CLIENT (OAuth2ClientProperties)
security.oauth2.client.client-id= # OAuth2 client id.
security.oauth2.client.client-secret= # OAuth2 client secret. A random
secret is generated by default
# SECURITY OAUTH2 SSO (OAuth2SsoProperties)
security.oauth2.sso.filter-order= # Filter order to apply if not
providing an explicit WebSecurityConfigurerAdapter
security.oauth2.sso.login-path=/login # Path to the login page, i.e.
the one that triggers the redirect to the OAuth2 Authorization Server
Spring Cloud Security
• Exemplo de proteção de um serviço com OAuth2
• Utilizando o servidor de autorização para validar os tokens
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
//...
}
security:
sessions: stateless
basic:
enabled: false
user:
password: none
oauth2:
resource:
preferTokenInfo: false
userInfoUri: http://localhost:9999/users/current
Spring Cloud Security
• Validando o token diretamente no cliente
security:
sessions: stateless
basic:
enabled: false
user:
password: none
oauth2:
resource:
jwt:
keyValue: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo1jWPfjvJxaXCHzvClU7
uJg+6AlZ8ht1Rbr+7Wo5o+YBWgCc6lZmSv/mwxvfL/wqagQ/W756a8vUJ7qFz/k9
eBSJQSRuzJ6pT4OMMR9gbmYroh3RM/Xd5RelJgT3+OrvjAZr1pFYdAwp0q1T9XPa
6PnCXq8KhIqNPxMjcaBrOycWEgWE4g4VnnrKDLtMmEZZIc0EMv8j7womsyNkbTyl
nPsbFttNwtFoTVJeqvD01Fd6ISaoOVQAUfAcxvp77B/A1g0No3GHBupEtW3Hgp2/
80Zl0+Gwjl6Wag5Mu9H7MIUPo+4xFGAJ0uwseHiErZqdWlHIo179IacB87+9Vt0g
pwIDAQAB
-----END PUBLIC KEY-----
• Suporte à definição de regras de segurança via anotações
• Habilita o suporte as anotações
• @PreAuthorize, @PostAuthorize, @Secured
• Suportando as expressões de segurança do Spring Security
• E também adicionando suporte as expressões OAuth2
Spring Cloud Security
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityMethodConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
• OAuth2SecurityExpressionMethods
• Expressões para restrição de segurança via OAuth2
• #oauth2.clientHasAnyRole('ADMIN', 'MANAGER')
• #oauth2.clientHasRole('MANAGER')
• #oauth2.denyOAuthClient()
• #oauth2.hasAnyScope('read', 'write')
• #oauth2.hasAnyScopeMatching('^abc .*', '[^a-z]{3}')
• #oauth2.hasScope('read')
• #oauth2.hasScopeMatching('^abc .*')
• #oauth2.isClient()
• #oauth2.isOAuth()
• #oauth2.isUser()
Spring Cloud Security
• Integração com Feign via OAuth2FeignRequestInterceptor
Spring Cloud Security
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Bean
public OAuth2FeignRequestInterceptor feignRequestInterceptor(
OAuth2ClientContext oAuth2ClientContext,
OAuth2ProtectedResourceDetails resource) {
return new OAuth2FeignRequestInterceptor(
oAuth2ClientContext, resource);
}
}
Laboratório 11 (cloud-lab11)
• Protegendo os microservices com Spring Cloud
Security
Spring Cloud Security
• É necessário proteger os demais serviços da aplicação
Spring Cloud Security
• Para proteger o Config Server
• É necessário habilitar restrição de acesso no Config Server
• Informar login e senha para conexão pelos clientes
security:
user:
name: configUser
password: configPassword
role: SYSTEM
spring:
cloud:
config:
uri: http://localhost:8888
username: configUser
password: configPassword
application.yml
bootstrap.yml
Spring Cloud Security
• Para proteger o Eureka Server
• É necessário habilitar segurança global no serviço Eureka
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("eurekaUser").password("eurekaPassword");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.httpBasic().and().csrf().disable()
.authorizeRequests().anyRequest().authenticated();
}
}
eureka:
client:
serviceUrl:
defaultZone: http://eurekaUser:eurekaPassword@localhost:8761/eureka
application.yml
Spring Cloud Security
• Para proteger o Hystrix Dashboard
• Necessário habilitar restrição de acesso nas propriedades
• Informar login e senha para acesso ao Hystrix Dashboard
• http://hystrixUser:hystrixPassword@localhost:7979/hystrix
• http://hystrixUser:hystrixPassword@localhost:7979/turbine.stream
security:
basic:
enabled: true
user:
name: hystrixUser
password: hystrixPassword
role: SYSTEM
application.yml
Laboratório 12 (cloud-lab12)
• Aplicando segurança nos serviços da plataforma
Spring Cloud
Roteamento
Roteamento
API Gateway
• Design pattern aplicado à microservices
• Requisições podem ser apenas repassadas, ou
modificadas
“Single entry point for the service clients”
Netflix Zuul
“Roteamento centralizado para microservices"
• Fornece único ponto de entrada para os serviços
• Roteamento e balanceamento na JVM
• Cria uma rota para cada serviço no Eureka
• Define filtros para pontos de entrada
• Similar outros roteamentos
• httpd, nginx, CF go router
Netflix Zuul
Netflix Zuul
Netflix Zuul
• Basta adicionar a dependência Maven
• Utilizar a anotação @EnableZuulProxy
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
@EnableZuulProxy
@SpringBootApplication
public class ZuulServer {
public static void main(String[] args) {
SpringApplication.run(ZuulServer.class, args);
}
}
Netflix Zuul
• @EnableZuulServer vs @EnableZuulProxy
• @EnableZuulServer
• Simples definição de um roteamento Zuul
• Deve ser utilizado para customização de código de roteamento sem
comportamento de proxy
• “Blank” Zuul server
• @EnableZuulProxy
• Modelo de uso mais comum
• Extensão do @EnableZuulServer
• Incorpora o suporte a proxy suportando a definição de routes na configuração
• Também suporta customização de código de roteamento por meio de filtros
Netflix Zuul
• Exemplo de configuração de rotas via URL
zuul:
routes:
first:
path: /first/**
url: http://first.example.com
second:
path: /second/**
url: forward:/second
third:
path: /third/**
url: forward:/3rd
legacy:
path: /**
url: http://legacy.example.com
Netflix Zuul
• Integração do Zuul com Eureka e Ribbon
Netflix Zuul
• Exemplo de utilização Zuul com Ribbon (serviceId)
zuul:
routes:
aluno-service:
path: /aluno/**
serviceId: aluno-service
disciplina-service:
path: /disciplina/**
serviceId: disciplina-service
ribbon:
eureka:
enabled: false
aluno-service:
ribbon:
listOfServers: localhost:8080,localhost:18080
disciplina-service:
ribbon:
listOfServers: localhost:8081,localhost:18081
Netflix Zuul
• Exemplo de utilização Zuul com Eureka (serviceId)
zuul:
routes:
aluno-service:
path: /aluno/**
serviceId: aluno-service
disciplina-service:
path: /disciplina/**
serviceId: disciplina-service
eureka:
client:
serviceUrl:
defaultZone: http://eurekaUser:eurekaPassword@localhost:8761/eureka
instance:
preferIpAddress: true
ribbon:
eureka:
enabled: true
Netflix Zuul
• Por padrão Zuul ignora alguns HTTP headers
• Pode-se customizar os sensitiveHeaders para definir quais headers devem
ser ignorados por rota definida
• Adicionalmente pode ser configurado
• zuul.ignoreHeaders
• Para ignorar headers globais (todos as rotas)
• zuul.ignoreSecurityHeaders
• True/false para ignorar os headers de segurança
• https://docs.spring.io/spring-security/site/docs/current/reference/html/
headers.html#default-security-headers
sensitiveHeaders: Cookie,Set-Cookie,Authorization
zuul:
routes:
users:
path: /myusers/**
sensitiveHeaders: IgnoredHeader1, X-Auth-Token
url: https://downstream
Netflix Zuul
• Demais configurações suportadas
• zuul.max.host.connections
• zuul.max.host.maxTotalConnections
• zuul.max.host.maxPerRouteConnections
• zuul.ribbonIsolationStrategy
• zuul.prefix
• zuul.stripPrefix
• zuul.retryable
• zuul.addProxyHeaders
• zuul.addHostHeader
• zuul.ignoredPatterns
• zuul.ignoredServices
• zuul.forceOriginalQueryStringEncoding
Laboratório 13 (cloud-lab13)
• Roteando os serviços com Netflix Zuul
Zuul Filter
• Lifecycle
Zuul Filter
• Basta implementar a interface IZuulFilter ou extender
a classe ZuulFilter
• Tipos de filtros
• PRE
• Executado antes de rotear à origem
• ROUTING
• Manipula a logica de roteamento do request à origem
• POST
• Executado após o request ter sido roteado à origem
• ERROR
• Executado quando algum erro acontece durante o roteamento
Zuul Filter
public class SimpleFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
return null;
}
}
Zuul Fallback
Zuul Fallback
class MyFallbackProvider implements ZuulFallbackProvider {
@Override
public String getRoute() {
return "customers"; // use "*" to all routes
}
@Override
public ClientHttpResponse fallbackResponse() {
//...
}
}
• Basta implementar um ZuulFallbackProvider
• getRoute() define em qual rota será aplicado
Zuul CORS
• CORS Overview
Zuul CORS
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source =
new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost:8080");
config.addAllowedOrigin("http://www.example.com");
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
• Pode ser ativado definindo um CorsFilter
Laboratório 14 (cloud-lab14)
• Implementando recursos avançados no Netflix
Zuul
Conclusões
• Microservices são sistemas distribuídos
• Sistemas distribuídos são essencialmente complexos
• Netflix OSS define ótimas ferramentas para
implementação de uma arquitetura de microservices
• Spring Cloud
• Ótima abstração para Netflix OSS
• Fácil utilização por meio de anotações
• Integrado com ecossistema Spring Boot
• Enjoy it :)
Revisão
Nessa unidade você teve a oportunidade de compreender como:
• Compreender as funcionalidades das plataformas Spring Cloud e Netflix
OSS
• Implementar um serviço de configuração centralizada utilizando Spring
Cloud Config
• Realizar o registro e descoberta dos serviços utilizando Netflix Eureka
• Suportar tolerância à falhas e balanceamento de carga na chamada
entre serviços com Netflix Ribbon
• Tornar os serviços mais resilientes com a implementação de circuit
breakers com Netflix Hystrix
• Orquestrar a implementação de segurança entre serviços com Spring
Cloud Security
• Implementar um serviço de proxy e/ou roteamento utilizando Netflix Zuul
Referências
• http://projects.spring.io/spring-cloud/
• https://netflix.github.io/
• http://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/1.3.1.RELEASE/
• http://cloud.spring.io/spring-cloud-static/spring-cloud-config/1.3.1.RELEASE/
• https://github.com/Netflix/ribbon
• https://github.com/Netflix/eureka
• https://github.com/Netflix/Hystrix
• https://ahus1.github.io/hystrix-examples/manual.html
• http://cloud.spring.io/spring-cloud-security/spring-cloud-security.html
• http://www.baeldung.com/spring-security-oauth-jwt
• http://www.baeldung.com/sso-spring-security-oauth2
• http://blog.monkey.codes/how-to-use-jwt-and-oauth-with-spring-boot/
• http://stytex.de/blog/2016/02/01/spring-cloud-security-with-oauth2/
• https://jmnarloch.wordpress.com/2015/10/14/spring-cloud-feign-oauth2-authentication/
• http://cloud.spring.io/spring-cloud-security/spring-cloud-security.html
• http://www.baeldung.com/spring-cloud-securing-services
• https://github.com/Netflix/zuul
• https://medium.com/netflix-techblog/announcing-zuul-edge-service-in-the-cloud-ab3af5be08ee
• http://callistaenterprise.se/blogg/teknik/2015/05/20/blog-series-building-microservices/

Mais conteúdo relacionado

Mais procurados

Microservice With Spring Boot and Spring Cloud
Microservice With Spring Boot and Spring CloudMicroservice With Spring Boot and Spring Cloud
Microservice With Spring Boot and Spring CloudEberhard Wolff
 
Microservices Design Patterns | Edureka
Microservices Design Patterns | EdurekaMicroservices Design Patterns | Edureka
Microservices Design Patterns | EdurekaEdureka!
 
Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...
Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...
Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...Simplilearn
 
The Beginner’s Guide To Spring Cloud
The Beginner’s Guide To Spring CloudThe Beginner’s Guide To Spring Cloud
The Beginner’s Guide To Spring CloudVMware Tanzu
 
Kubernetes Architecture
 Kubernetes Architecture Kubernetes Architecture
Kubernetes ArchitectureKnoldus Inc.
 
Docker introduction
Docker introductionDocker introduction
Docker introductionPhuc Nguyen
 
DevJam 2019 - Introduction to Kubernetes
DevJam 2019 - Introduction to KubernetesDevJam 2019 - Introduction to Kubernetes
DevJam 2019 - Introduction to KubernetesRonny Trommer
 
Alphorm.com Microsoft AZURE
Alphorm.com Microsoft AZUREAlphorm.com Microsoft AZURE
Alphorm.com Microsoft AZUREAlphorm
 
Introduction to GitHub Actions
Introduction to GitHub ActionsIntroduction to GitHub Actions
Introduction to GitHub ActionsKnoldus Inc.
 
Introdução ao Desenvolvimento Android
Introdução ao Desenvolvimento AndroidIntrodução ao Desenvolvimento Android
Introdução ao Desenvolvimento AndroidJosé Alexandre Macedo
 
Advancements in Kubernetes Workload Identity for Azure
Advancements in Kubernetes Workload Identity for AzureAdvancements in Kubernetes Workload Identity for Azure
Advancements in Kubernetes Workload Identity for AzureLibbySchulze
 
Best practices for Terraform with Vault
Best practices for Terraform with VaultBest practices for Terraform with Vault
Best practices for Terraform with VaultMitchell Pronschinske
 

Mais procurados (20)

Spring Data Jpa
Spring Data JpaSpring Data Jpa
Spring Data Jpa
 
Spring cloud config
Spring cloud configSpring cloud config
Spring cloud config
 
Microservice With Spring Boot and Spring Cloud
Microservice With Spring Boot and Spring CloudMicroservice With Spring Boot and Spring Cloud
Microservice With Spring Boot and Spring Cloud
 
Spring Cloud Config
Spring Cloud ConfigSpring Cloud Config
Spring Cloud Config
 
Docker introduction
Docker introductionDocker introduction
Docker introduction
 
Microservices Design Patterns | Edureka
Microservices Design Patterns | EdurekaMicroservices Design Patterns | Edureka
Microservices Design Patterns | Edureka
 
Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...
Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...
Docker Tutorial For Beginners | What Is Docker And How It Works? | Docker Tut...
 
The Beginner’s Guide To Spring Cloud
The Beginner’s Guide To Spring CloudThe Beginner’s Guide To Spring Cloud
The Beginner’s Guide To Spring Cloud
 
Kubernetes Architecture
 Kubernetes Architecture Kubernetes Architecture
Kubernetes Architecture
 
Docker introduction
Docker introductionDocker introduction
Docker introduction
 
Container Orchestration
Container OrchestrationContainer Orchestration
Container Orchestration
 
DevJam 2019 - Introduction to Kubernetes
DevJam 2019 - Introduction to KubernetesDevJam 2019 - Introduction to Kubernetes
DevJam 2019 - Introduction to Kubernetes
 
Alphorm.com Microsoft AZURE
Alphorm.com Microsoft AZUREAlphorm.com Microsoft AZURE
Alphorm.com Microsoft AZURE
 
Introduction to GitHub Actions
Introduction to GitHub ActionsIntroduction to GitHub Actions
Introduction to GitHub Actions
 
Kubernetes 101
Kubernetes 101Kubernetes 101
Kubernetes 101
 
Introdução ao Desenvolvimento Android
Introdução ao Desenvolvimento AndroidIntrodução ao Desenvolvimento Android
Introdução ao Desenvolvimento Android
 
Quick introduction to Kubernetes
Quick introduction to KubernetesQuick introduction to Kubernetes
Quick introduction to Kubernetes
 
Advancements in Kubernetes Workload Identity for Azure
Advancements in Kubernetes Workload Identity for AzureAdvancements in Kubernetes Workload Identity for Azure
Advancements in Kubernetes Workload Identity for Azure
 
Best practices for Terraform with Vault
Best practices for Terraform with VaultBest practices for Terraform with Vault
Best practices for Terraform with Vault
 
Docker on Docker
Docker on DockerDocker on Docker
Docker on Docker
 

Semelhante a Microservices com Spring Cloud e Netflix OSS

QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...
QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...
QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...Rodrigo Cândido da Silva
 
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetesk6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
k6: Performance Engineering, Monitoramento e Teste de um HPA no KubernetesKelvin Silva
 
ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - .NET SP...
ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - .NET SP...ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - .NET SP...
ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - .NET SP...Renato Groff
 
ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - Develop...
ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - Develop...ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - Develop...
ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - Develop...Renato Groff
 
TDC2011: Java EE 6 & Azure
TDC2011: Java EE 6 & AzureTDC2011: Java EE 6 & Azure
TDC2011: Java EE 6 & AzureDr. Spock
 
The twelve factor apps and openruko
The twelve factor apps and openrukoThe twelve factor apps and openruko
The twelve factor apps and openrukoÉverton Ribeiro
 
ASP.NET Core + Kubernetes + Azure - Community Bootcamp - Abril/2018
ASP.NET Core + Kubernetes + Azure - Community Bootcamp - Abril/2018ASP.NET Core + Kubernetes + Azure - Community Bootcamp - Abril/2018
ASP.NET Core + Kubernetes + Azure - Community Bootcamp - Abril/2018Renato Groff
 
Datacenter na nuvem
Datacenter na nuvemDatacenter na nuvem
Datacenter na nuvemIgnacio Nin
 
13.+Introdução+-+Prometheus.pdf
13.+Introdução+-+Prometheus.pdf13.+Introdução+-+Prometheus.pdf
13.+Introdução+-+Prometheus.pdfLuizCarlos412334
 
Workshop Microservices - Distribuindo os Microservices com Docker e Kubernetes
Workshop Microservices - Distribuindo os Microservices com Docker e KubernetesWorkshop Microservices - Distribuindo os Microservices com Docker e Kubernetes
Workshop Microservices - Distribuindo os Microservices com Docker e KubernetesRodrigo Cândido da Silva
 
Transformando seu datacenter em nuvem privada
Transformando seu datacenter em nuvem privadaTransformando seu datacenter em nuvem privada
Transformando seu datacenter em nuvem privadaJuscélio Reis
 
Docker de ponta a ponta - do Desenvolvimento à Nuvem - .NET SP - Outubro-2018
Docker de ponta a ponta - do Desenvolvimento à Nuvem - .NET SP - Outubro-2018Docker de ponta a ponta - do Desenvolvimento à Nuvem - .NET SP - Outubro-2018
Docker de ponta a ponta - do Desenvolvimento à Nuvem - .NET SP - Outubro-2018Renato Groff
 
Docker de ponta a ponta: do Desenvolvimento à Nuvem - Azure Talks - Agosto-2018
Docker de ponta a ponta: do Desenvolvimento à Nuvem - Azure Talks - Agosto-2018Docker de ponta a ponta: do Desenvolvimento à Nuvem - Azure Talks - Agosto-2018
Docker de ponta a ponta: do Desenvolvimento à Nuvem - Azure Talks - Agosto-2018Renato Groff
 
Ferramentas para Automação de Datacenter
Ferramentas para Automação de DatacenterFerramentas para Automação de Datacenter
Ferramentas para Automação de DatacenterWilson Lopes
 
Ferramentas para Automação de Datacenter - GTER 37
Ferramentas para Automação de Datacenter - GTER 37Ferramentas para Automação de Datacenter - GTER 37
Ferramentas para Automação de Datacenter - GTER 37Wilson Lopes
 
TDC Floripa 2016 - Decolando seus micro-serviços na Spring Cloud
TDC Floripa 2016 - Decolando seus micro-serviços na Spring CloudTDC Floripa 2016 - Decolando seus micro-serviços na Spring Cloud
TDC Floripa 2016 - Decolando seus micro-serviços na Spring CloudRodrigo Cândido da Silva
 
Segurança em Plataforma Microsoft
Segurança em Plataforma MicrosoftSegurança em Plataforma Microsoft
Segurança em Plataforma MicrosoftUilson Souza
 
Microservices com Spring Boot e Spring Cloud Netflix
Microservices com Spring Boot e Spring Cloud NetflixMicroservices com Spring Boot e Spring Cloud Netflix
Microservices com Spring Boot e Spring Cloud NetflixNatanael Fonseca
 
Building blocks #4 - Rede de entrega de conteúdo (CDN) na AWS
Building blocks #4 - Rede de entrega de conteúdo (CDN) na AWSBuilding blocks #4 - Rede de entrega de conteúdo (CDN) na AWS
Building blocks #4 - Rede de entrega de conteúdo (CDN) na AWSAmazon Web Services LATAM
 

Semelhante a Microservices com Spring Cloud e Netflix OSS (20)

QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...
QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...
QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...
 
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetesk6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
 
ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - .NET SP...
ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - .NET SP...ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - .NET SP...
ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - .NET SP...
 
ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - Develop...
ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - Develop...ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - Develop...
ASP.NET Core + Kubernetes + Azure: Orquestrando containers na nuvem - Develop...
 
TDC2011: Java EE 6 & Azure
TDC2011: Java EE 6 & AzureTDC2011: Java EE 6 & Azure
TDC2011: Java EE 6 & Azure
 
The twelve factor apps and openruko
The twelve factor apps and openrukoThe twelve factor apps and openruko
The twelve factor apps and openruko
 
ASP.NET Core + Kubernetes + Azure - Community Bootcamp - Abril/2018
ASP.NET Core + Kubernetes + Azure - Community Bootcamp - Abril/2018ASP.NET Core + Kubernetes + Azure - Community Bootcamp - Abril/2018
ASP.NET Core + Kubernetes + Azure - Community Bootcamp - Abril/2018
 
Datacenter na nuvem
Datacenter na nuvemDatacenter na nuvem
Datacenter na nuvem
 
13.+Introdução+-+Prometheus.pdf
13.+Introdução+-+Prometheus.pdf13.+Introdução+-+Prometheus.pdf
13.+Introdução+-+Prometheus.pdf
 
Workshop Microservices - Distribuindo os Microservices com Docker e Kubernetes
Workshop Microservices - Distribuindo os Microservices com Docker e KubernetesWorkshop Microservices - Distribuindo os Microservices com Docker e Kubernetes
Workshop Microservices - Distribuindo os Microservices com Docker e Kubernetes
 
Transformando seu datacenter em nuvem privada
Transformando seu datacenter em nuvem privadaTransformando seu datacenter em nuvem privada
Transformando seu datacenter em nuvem privada
 
Docker de ponta a ponta - do Desenvolvimento à Nuvem - .NET SP - Outubro-2018
Docker de ponta a ponta - do Desenvolvimento à Nuvem - .NET SP - Outubro-2018Docker de ponta a ponta - do Desenvolvimento à Nuvem - .NET SP - Outubro-2018
Docker de ponta a ponta - do Desenvolvimento à Nuvem - .NET SP - Outubro-2018
 
Docker de ponta a ponta: do Desenvolvimento à Nuvem - Azure Talks - Agosto-2018
Docker de ponta a ponta: do Desenvolvimento à Nuvem - Azure Talks - Agosto-2018Docker de ponta a ponta: do Desenvolvimento à Nuvem - Azure Talks - Agosto-2018
Docker de ponta a ponta: do Desenvolvimento à Nuvem - Azure Talks - Agosto-2018
 
Ferramentas para Automação de Datacenter
Ferramentas para Automação de DatacenterFerramentas para Automação de Datacenter
Ferramentas para Automação de Datacenter
 
Ferramentas para Automação de Datacenter - GTER 37
Ferramentas para Automação de Datacenter - GTER 37Ferramentas para Automação de Datacenter - GTER 37
Ferramentas para Automação de Datacenter - GTER 37
 
TDC Floripa 2016 - Decolando seus micro-serviços na Spring Cloud
TDC Floripa 2016 - Decolando seus micro-serviços na Spring CloudTDC Floripa 2016 - Decolando seus micro-serviços na Spring Cloud
TDC Floripa 2016 - Decolando seus micro-serviços na Spring Cloud
 
De 0 a DevOps
De 0 a DevOpsDe 0 a DevOps
De 0 a DevOps
 
Segurança em Plataforma Microsoft
Segurança em Plataforma MicrosoftSegurança em Plataforma Microsoft
Segurança em Plataforma Microsoft
 
Microservices com Spring Boot e Spring Cloud Netflix
Microservices com Spring Boot e Spring Cloud NetflixMicroservices com Spring Boot e Spring Cloud Netflix
Microservices com Spring Boot e Spring Cloud Netflix
 
Building blocks #4 - Rede de entrega de conteúdo (CDN) na AWS
Building blocks #4 - Rede de entrega de conteúdo (CDN) na AWSBuilding blocks #4 - Rede de entrega de conteúdo (CDN) na AWS
Building blocks #4 - Rede de entrega de conteúdo (CDN) na AWS
 

Mais de Rodrigo Cândido da Silva

Protegendo Microservices: Boas Práticas e Estratégias de Implementação
Protegendo Microservices: Boas Práticas e Estratégias de ImplementaçãoProtegendo Microservices: Boas Práticas e Estratégias de Implementação
Protegendo Microservices: Boas Práticas e Estratégias de ImplementaçãoRodrigo Cândido da Silva
 
Protecting Java Microservices: Best Practices and Strategies
Protecting Java Microservices: Best Practices and StrategiesProtecting Java Microservices: Best Practices and Strategies
Protecting Java Microservices: Best Practices and StrategiesRodrigo Cândido da Silva
 
TDC Floripa 2017 - Criando Microservices Reativos com Java
TDC Floripa 2017 - Criando Microservices Reativos com JavaTDC Floripa 2017 - Criando Microservices Reativos com Java
TDC Floripa 2017 - Criando Microservices Reativos com JavaRodrigo Cândido da Silva
 
GUJavaSC - Combinando Micro-serviços com Práticas DevOps
GUJavaSC - Combinando Micro-serviços com Práticas DevOpsGUJavaSC - Combinando Micro-serviços com Práticas DevOps
GUJavaSC - Combinando Micro-serviços com Práticas DevOpsRodrigo Cândido da Silva
 
GUJavaSC - Criando Micro-serviços Reativos com Java
GUJavaSC - Criando Micro-serviços Reativos com JavaGUJavaSC - Criando Micro-serviços Reativos com Java
GUJavaSC - Criando Micro-serviços Reativos com JavaRodrigo Cândido da Silva
 
JavaOne 2016 - Reactive Microservices with Java and Java EE
JavaOne 2016 - Reactive Microservices with Java and Java EEJavaOne 2016 - Reactive Microservices with Java and Java EE
JavaOne 2016 - Reactive Microservices with Java and Java EERodrigo Cândido da Silva
 
JavaOne LATAM 2016 - Combinando AngularJS com Java EE
JavaOne LATAM 2016 - Combinando AngularJS com Java EEJavaOne LATAM 2016 - Combinando AngularJS com Java EE
JavaOne LATAM 2016 - Combinando AngularJS com Java EERodrigo Cândido da Silva
 
JavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data REST
JavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data RESTJavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data REST
JavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data RESTRodrigo Cândido da Silva
 
QCon 2015 - Combinando AngularJS com Java EE
QCon 2015 - Combinando AngularJS com Java EEQCon 2015 - Combinando AngularJS com Java EE
QCon 2015 - Combinando AngularJS com Java EERodrigo Cândido da Silva
 
JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2
JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2
JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2Rodrigo Cândido da Silva
 
JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...
JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...
JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...Rodrigo Cândido da Silva
 
TDC 2015 - Segurança em Recursos RESTful com OAuth2
TDC 2015 - Segurança em Recursos RESTful com OAuth2TDC 2015 - Segurança em Recursos RESTful com OAuth2
TDC 2015 - Segurança em Recursos RESTful com OAuth2Rodrigo Cândido da Silva
 
ConFoo 2015 - Supporting Multi-tenancy Applications with Java EE
ConFoo 2015 - Supporting Multi-tenancy Applications with Java EEConFoo 2015 - Supporting Multi-tenancy Applications with Java EE
ConFoo 2015 - Supporting Multi-tenancy Applications with Java EERodrigo Cândido da Silva
 
ConFoo 2015 - Securing RESTful resources with OAuth2
ConFoo 2015 - Securing RESTful resources with OAuth2ConFoo 2015 - Securing RESTful resources with OAuth2
ConFoo 2015 - Securing RESTful resources with OAuth2Rodrigo Cândido da Silva
 

Mais de Rodrigo Cândido da Silva (20)

Java 9, 10 e ... 11
Java 9, 10 e ... 11Java 9, 10 e ... 11
Java 9, 10 e ... 11
 
Cloud Native Java EE
Cloud Native Java EECloud Native Java EE
Cloud Native Java EE
 
Protegendo Microservices: Boas Práticas e Estratégias de Implementação
Protegendo Microservices: Boas Práticas e Estratégias de ImplementaçãoProtegendo Microservices: Boas Práticas e Estratégias de Implementação
Protegendo Microservices: Boas Práticas e Estratégias de Implementação
 
Protecting Java Microservices: Best Practices and Strategies
Protecting Java Microservices: Best Practices and StrategiesProtecting Java Microservices: Best Practices and Strategies
Protecting Java Microservices: Best Practices and Strategies
 
As novidades da nova versão do Java 9
As novidades da nova versão do Java 9As novidades da nova versão do Java 9
As novidades da nova versão do Java 9
 
GUJavaSC - Protegendo Microservices em Java
GUJavaSC - Protegendo Microservices em JavaGUJavaSC - Protegendo Microservices em Java
GUJavaSC - Protegendo Microservices em Java
 
TDC Floripa 2017 - Criando Microservices Reativos com Java
TDC Floripa 2017 - Criando Microservices Reativos com JavaTDC Floripa 2017 - Criando Microservices Reativos com Java
TDC Floripa 2017 - Criando Microservices Reativos com Java
 
GUJavaSC - Combinando Micro-serviços com Práticas DevOps
GUJavaSC - Combinando Micro-serviços com Práticas DevOpsGUJavaSC - Combinando Micro-serviços com Práticas DevOps
GUJavaSC - Combinando Micro-serviços com Práticas DevOps
 
GUJavaSC - Criando Micro-serviços Reativos com Java
GUJavaSC - Criando Micro-serviços Reativos com JavaGUJavaSC - Criando Micro-serviços Reativos com Java
GUJavaSC - Criando Micro-serviços Reativos com Java
 
JavaOne 2016 - Reactive Microservices with Java and Java EE
JavaOne 2016 - Reactive Microservices with Java and Java EEJavaOne 2016 - Reactive Microservices with Java and Java EE
JavaOne 2016 - Reactive Microservices with Java and Java EE
 
JavaOne LATAM 2016 - Combinando AngularJS com Java EE
JavaOne LATAM 2016 - Combinando AngularJS com Java EEJavaOne LATAM 2016 - Combinando AngularJS com Java EE
JavaOne LATAM 2016 - Combinando AngularJS com Java EE
 
JavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data REST
JavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data RESTJavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data REST
JavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data REST
 
GUJavaSC - Combinando AngularJS com Java EE
GUJavaSC - Combinando AngularJS com Java EEGUJavaSC - Combinando AngularJS com Java EE
GUJavaSC - Combinando AngularJS com Java EE
 
QCon 2015 - Combinando AngularJS com Java EE
QCon 2015 - Combinando AngularJS com Java EEQCon 2015 - Combinando AngularJS com Java EE
QCon 2015 - Combinando AngularJS com Java EE
 
JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2
JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2
JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2
 
JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...
JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...
JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...
 
TDC 2015 - Segurança em Recursos RESTful com OAuth2
TDC 2015 - Segurança em Recursos RESTful com OAuth2TDC 2015 - Segurança em Recursos RESTful com OAuth2
TDC 2015 - Segurança em Recursos RESTful com OAuth2
 
ConFoo 2015 - Supporting Multi-tenancy Applications with Java EE
ConFoo 2015 - Supporting Multi-tenancy Applications with Java EEConFoo 2015 - Supporting Multi-tenancy Applications with Java EE
ConFoo 2015 - Supporting Multi-tenancy Applications with Java EE
 
ConFoo 2015 - Securing RESTful resources with OAuth2
ConFoo 2015 - Securing RESTful resources with OAuth2ConFoo 2015 - Securing RESTful resources with OAuth2
ConFoo 2015 - Securing RESTful resources with OAuth2
 
GUJavaSC - Unit Testing com Java EE
GUJavaSC - Unit Testing com Java EEGUJavaSC - Unit Testing com Java EE
GUJavaSC - Unit Testing com Java EE
 

Microservices com Spring Cloud e Netflix OSS

  • 1. Workshop Microservices Microservices com Spring Cloud e Netflix OSS
  • 2. Objetivos • Ao final desta unidade você compreenderá como: • Compreender as funcionalidades das plataformas Spring Cloud e Netflix OSS • Implementar um serviço de configuração centralizada utilizando Spring Cloud Config • Realizar o registro e descoberta dos serviços utilizando Netflix Eureka • Suportar tolerância à falhas e balanceamento de carga na chamada entre serviços com Netflix Ribbon • Tornar os serviços mais resilientes com a implementação de circuit breakers com Netflix Hystrix • Orquestrar a implementação de segurança entre serviços com Spring Cloud Security • Implementar um serviço de proxy e/ou roteamento utilizando Netflix Zuul
  • 3. Agenda • Spring Cloud e Netflix OSS • Spring Cloud Config • Netflix Eureka • Netflix Ribbon e Feign • Netflix Hystrix • Spring Cloud Security • Netflix Zuul
  • 5. Microservices • Quais os principais desafios? • Gerenciamento de configuração • Registro e descoberta dos serviços • Roteamento • Balanceamento de carga • Tolerância à falhas
  • 6.
  • 7.
  • 8.
  • 9. • Eureka • Hystrix • Ribbon • Zuul • + muitos outros… • API • Routing / Health check • Microservices • Logging • Data Management
  • 10. Spring Cloud • Conjunto de bibliotecas / componentes • Não é apenas uma ferramenta • Integrado ao Spring Boot • Suporta diferentes arquiteturas e tecnologias em Cloud • AWS, Netflix, Heroku, Cloud Foundry, etc • Facilita a implementação de padrões necessários aos sistemas distribuídos “Toolset designed for building distributed systems”
  • 13. Spring Cloud Component Camden.SR7 Dalston.RELEASE spring-cloud-aws 1.1.4.RELEASE 1.2.0.RELEASE spring-cloud-bus 1.2.2.RELEASE 1.3.0.RELEASE spring-cloud-cli 1.2.4.RELEASE 1.3.1.RELEASE spring-cloud-commons 1.1.9.RELEASE 1.3.0.RELEASE spring-cloud-contract 1.0.5.RELEASE 1.1.0.RELEASE spring-cloud-config 1.2.3.RELEASE 1.3.0.RELEASE spring-cloud-netflix 1.2.7.RELEASE 1.3.0.RELEASE spring-cloud-security 1.1.4.RELEASE 1.2.0.RELEASE spring-cloud-cloudfoundry 1.0.1.RELEASE 1.1.0.RELEASE spring-cloud-consul 1.1.4.RELEASE 1.2.0.RELEASE spring-cloud-sleuth 1.1.3.RELEASE 1.2.0.RELEASE spring-cloud-stream Brooklyn.SR3 Chelsea.SR1 spring-cloud-zookeeper 1.0.4.RELEASE 1.1.0.RELEASE spring-boot 1.4.5.RELEASE 1.5.2.RELEASE spring-cloud-task 1.0.3.RELEASE 1.1.3.RELEASE
  • 14. Spring Cloud • Para adicionar no projeto basta incluir parent POM <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
  • 15. Spring Cloud + Netflix OSS "Casamento perfeito para criação de microservices auto-curáveis" Gerenciamento de configuração Spring Cloud Config + Bus Descoberta de serviços Netflix Eureka Balanceamento de carga Netflix Ribbon Tolerância à falhas Netflix Hystrix + Turbine Roteamento Netflix Zuul Segurança Spring Cloud Security
  • 16. Spring Cloud + Netflix OSS
  • 18. Spring Cloud Config “Gerenciamento de configuração para micro-serviços“ • Centraliza a configuração da aplicação • Permite atualizações dinâmicas • Suporta versionamento • Suporte à rollback • Suporta configuração via repositórios • Git, SVN, filesystem • Permite atualização via barramento • Spring Cloud Bus
  • 19. Spring Cloud Config • Serviço de configuração centralizado
  • 20. Spring Cloud Config (server) • Basta adicionar a dependência Maven • Utilizar a anotação @EnableConfigServer <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> @EnableConfigServer @SpringBootApplication public class ConfigServer { public static void main(String[] args) { SpringApplication.run(ConfigServer.class, args); } }
  • 21. Spring Cloud Config (server) • É necessário também configurar o repositório com as configurações externas server: port: 8888 spring: cloud: config: server: git: uri: file://config-repo $ cd $HOME $ mkdir config-repo $ cd config-repo $ git init . $ echo foo > application.properties $ git add -A . $ git commit -m “Initial commit"
  • 22. Spring Cloud Config (server) @SpringBootApplication @EnableConfigServer public class ConfigServer {...} spring.cloud.config.git.uri: https://github.com/... ConfigServer.java application.yml
  • 23. Spring Cloud Config (server) • É possível customizar configurações para utilização do repositório Git spring: cloud: config: server: git: uri: https://github.com/spring-cloud-samples/config-repo username: trolley password: strongpassword default-label: master force-pull: true basedir: file://server/local/path timeout: 60 clone-on-start: true search-paths: foo,bar*
  • 24. Spring Cloud Config (server) • Suporta também utilização de diferentes repositórios Git de acordo com um padrão / perfil definido (12-factor) spring: cloud: config: server: git: uri: https://github.com/spring-cloud-samples/config-repo repos: development: pattern: - */development - */staging uri: https://github.com/development/config-repo staging: pattern: - */qa - */production uri: https://github.com/staging/config-repo
  • 25. Spring Cloud Config (server) • Exemplo com configuração para SVN repo • Exemplo com configuração para Filesystem spring: profiles: active: subversion cloud: config: server: svn: uri: https://svn/config-repo default-label: trunk spring: profiles: active: native cloud: config: server: native: searchLocations: file://local/config-repo
  • 26. Spring Cloud Config (server) • Suporta a manipulação de diferentes Spring Profiles • Basta acessar as configurações via HTTP REST no seguinte formato • /{application}/{profile}[/{label}] • /{application}-{profile}.yml • /{label}/{application}-{profile}.yml • /{application}-{profile}.properties • /{label}/{application}-{profile}.properties • YML • Você configura dentro do próprio arquivo • Separando por --- • Properties • application.properties • application-dev.properties • application-prod.properties logging: level: debug --- spring: profiles: dev, prod logging: level: info application.yml
  • 28. Spring Cloud Config (client) • Basta adicionar a dependência Maven • Configurar o arquivo bootstrap.yml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> spring: application: name: microservice1 cloud: config: uri: http://localhost:8888
  • 29. Spring Cloud Config (client) @RefreshScope @Component public class AppComponent { @Value("${thread-pool}") private int threadPool; @Value("${email}") private String email; @Autowired Environment env } • É possível buscar as propriedades definidas pelo Config Server utilizando @Value e Spring Environment • Existe a possibilidade de atualizar as propriedades sem derrubar a aplicação, utilizando a anotação @RefreshScope • POST http://localhost:8080/refresh
  • 30. Laboratório 1 (cloud-lab01) • Centralizando a configuração com Spring Cloud Config
  • 32. • Exemplo da arquitetura de replicação de configuração utilizada Spring Cloud Config + Bus
  • 33. • Lightweight AMQP Messaging Broker • Arquitetura flexível e fornece extensões para outros protocolos • HTTP, STOMP, MQTT • Ótima integração com Spring • Spring Boot, Cloud Bus, Cloud Stream, Messaging • Instalação • Windows • https://www.rabbitmq.com/install-windows.html • Mac OS X • brew install rabbitmq • Linux • apt-get install rabbitmq-server • yum install rabbitmq-server • Web Console • http://localhost:15672 • user: guest / password: guest RabbitMQ
  • 34. Spring Cloud Config + Bus (server) • É necessário adicionar as seguintes dependências • É suportado também a utilização de Kafka ou Redis como implementação do barramento <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-monitor</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency> spring: cloud: bus: enabled: true rabbitmq: host: localhost port: 5672 • Deve ser ativado o suporte ao barramento via properties
  • 35. Spring Cloud Config + Bus (client) • É necessário adicionar as seguintes dependências • Incorporar a seguinte configuração no bootstrap.yml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> spring: application: name: microservice1 cloud: config: uri: http://localhost:8888 rabbitmq: host: localhost port: 5672
  • 36. Spring Cloud Config + Bus • Configuração do Webhook no repositório Git
  • 37. Laboratório 2 (cloud-lab02) • Replicando a configuração centralizada com Spring Cloud Config Bus
  • 38. Registro e Descoberta de Serviços
  • 39. Registro e Descoberta de Serviços
  • 40. Registro e Descoberta de Serviços
  • 41. Registro e Descoberta de Serviços Service Register Health Check
  • 42. Netflix Eureka "Transparência de localização aos micro-serviços“ • Registro de serviços REST based • Suporte à replicação • Cache aplicado no stub cliente • Resiliente • Rápido… mas não consistente • Fornece o alicerce para outros serviços • Mantém registro de clientes com metadados
  • 43. Netflix Eureka (server) • Basta adicionar a dependência Maven • Utilizar a anotação @EnableEurekaServer <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> @SpringBootApplication @EnableEurekaServer public class EurekaServer { public static void main(String[] args) { SpringApplication.run(EurekaServer.class, args); } }
  • 44. Netflix Eureka (server) • Exemplo de configuração básica application.yml • Para acessar o Eureka Dashboard Web • http://localhost:8761 server: port: 8761 eureka: instance: hostname: localhost client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  • 47. Netflix Eureka (client) • Basta adicionar a dependência Maven • Utilizar a anotação @EnableDiscoveryClient <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> @EnableDiscoveryClient @SpringBootApplication public class EurekaClient { public static void main(String[] args) { SpringApplication.run(EurekaClient.class, args); } }
  • 48. Netflix Eureka (client) • Exemplo de configuração básica application.yml • Cliente será registrado no Eureka Server spring: application: name: spring-cloud-eureka-client eureka: client: serviceUrl: defaultZone: ${EUREKA_URI:http://localhost:8761/eureka} instance: preferIpAddress: true
  • 49. Netflix Eureka (client) • Exemplo utilizando DiscoveryClient @RestController public class ProductController { @Autowired DiscoveryClient discoveryClient; @GetMapping("/get/customers") public void getCustomers() throws Exception { List<ServiceInstance> instances = discoveryClient.getInstances("customer-service"); ServiceInstance firstOne = instances.get(0); String uri = "http://" + firstOne.getHost() + ":" + firstOne.getPort(); HttpGet getRequest = new HttpGet(uri + "/customers"); DefaultHttpClient httpClient = new DefaultHttpClient(); HttpResponse response = httpClient.execute(getRequest); // ... } }
  • 50. Netflix Eureka (client) • Exemplo utilizando RestTemplate @RestController public class ProductController { @Autowired RestTemplate restTemplate; @GetMapping("/get/customers") public void getCustomers() throws Exception { // use the "smart" Eureka-aware RestTemplate ResponseEntity<List<CustomerDTO>> exchange = this.restTemplate.exchange( "http://customer-service/customers", HttpMethod.GET, null, new ParameterizedTypeReference<List<CustomerDTO>>() {}, (Object) null); // ... } }
  • 51. Laboratório 3 (cloud-lab03) • Registrando e descobrindo serviços com Netflix Eureka
  • 54. Netflix Eureka • Para configurar o mecanismo de suporte à replicação --- spring: profiles: peer1 eureka: instance: hostname: peer1 client: serviceUrl: defaultZone: http://peer2:[port]/eureka/ --- spring: profiles: peer2 eureka: instance: hostname: peer2 client: serviceUrl: defaultZone: http://peer1:[port]/eureka/ ## Hosts / IPs peer1 127.0.0.1 peer2 127.0.0.1 /etc/hosts application.yml
  • 56. Laboratório 4 (cloud-lab04) • Ativando o suporte à replicação com Netflix Eureka
  • 59. Netflix Ribbon "Balanceamento de carga para microservices" • Balanceamento decentralizado no cliente • Resiliente • Suporte à tolerância a falhas • Trabalha com múltiplos protocolos • HTTP, TCP, UDP • Modelo assíncrono e reativo • Suporte à caching e batching • Múltiplos algoritmos de balanceamento
  • 61. Netflix Ribbon • Basta adicionar a dependência Maven • Pode ser utilizado de duas maneiras • Diretamente (sem Eureka) • Por meio do objeto LoadBalancerClient • Utilizando configurações na aplicação • Properties, Ribbon Client Configuration • Por meio de anotações • @RibbonClient, @LoadBalanced • Integrado (com Eureka) • Pode ser customizado via propriedades <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency>
  • 62. Netflix Ribbon • Exemplo de configuração do Ribbon client public class GroupRibbonConfiguration { @Autowired IClientConfig ribbonClientConfig; @Bean public IPing ribbonPing(IClientConfig config) { return new PingUrl(); } @Bean public IRule ribbonRule(IClientConfig config) { return new AvailabilityFilteringRule(); } } group-service: ribbon: eureka: enabled: false listOfServers: localhost:9092,localhost:9999 ServerListRefreshInterval: 15000
  • 63. Netflix Ribbon • Configurações possíveis para Ribbon Configuration • IClientConfig • Define a configuração para o cliente do load balancer • ServerList<Server> • Define como recuperar a lista de servidores para escolha • ServerListFilter<Server> • Define uma lista de filtro para a lista de servidores para escolha • ILoanBalancer • Representa o software de load balancer • IRule • Descreve a estratégia de load balancing • IPing • Define qual a periodicidade dos pings realizados
  • 64. Netflix Ribbon • Configurações possíveis para IRule • AvailabilityFilteringRule • ClientConfigEnabledRoundRobinRule • RandomRule • ResponseTimeWeightedRule • RetryRule • RoundRobinRule • WeightedResponseTimeRule • ZoneAvoidanceRule
  • 65. Netflix Ribbon • Configurações possíveis para ILoadBalancer • BaseLoadBalancer • DynamicServerListLoadBalancer • NoOpLoadBalancer • ZoneAwareLoadBalancer • Configurações possíveis para IPing • DummyPing • NoOpPing • PingConstant
  • 66. Netflix Ribbon • Uso direto via LoadBalancerClient @RestController @RibbonClient(name = "group-service", configuration = GroupRibbonConfiguration.class) public class UserController { @Autowired LoadBalancerClient loadBalancer; @RequestMapping("/users/{id}/group") public Group userGroup(@PathVariable Long id) { ServiceInstance instance = loadBalancer.choose("group-service"); URI storesUri = URI.create(String.format(“http://%s:%s", instance.getHost(), instance.getPort())); // ... do something with the URI } }
  • 67. Netflix Ribbon • Uso direto via @LoadBalanced @RestController @RibbonClient(name = "group-service", configuration = GroupRibbonConfiguration.class) public class UserController { @LoadBalanced @Bean RestTemplate restTemplate(){ return new RestTemplate(); } @Autowired RestTemplate restTemplate; @RequestMapping("/users/{id}/group") public Group userGroup(@PathVariable Long id) { return this.restTemplate.getForObject( "http://group-service/user/" + id, Group.class); } }
  • 68. Netflix Ribbon @EnableDiscoveryClient @SpringBootApplication public class RibbonEurekaClient { public static void main(String[] args) { SpringApplication.run(RibbonEurekaClient.class, args); } } spring: application: name: ribbon-client eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka instance: preferIpAddress: true • Exemplo de uso com Eureka
  • 69. Netflix Ribbon • Exemplo de uso com Eureka • group-service é um serviço registrado no Eureka @RestController public class UserController { @LoadBalanced @Bean RestTemplate restTemplate(){ return new RestTemplate(); } @Autowired RestTemplate restTemplate; @RequestMapping("/users/{id}/group") public Group userGroup(@PathVariable Long id) { return this.restTemplate.getForObject( "http://group-service/user/" + id, Group.class); } }
  • 70. Laboratório 5 (cloud-lab05) • Implementando balanceamento de carga e tolerância à falhas com Netflix Ribbon
  • 71. Netflix Feign • Facilita criação de clientes REST • Ótima integração com Spring Cloud • Suporta implementação de circuit breakers • Simples, produtivo e customizável • Pode ser utilizado em conjunto com • Ribbon - balanceamento de carga • Eureka - descoberta dos serviços “Declarative REST interfaces"
  • 72. Netflix Feign • Basta adicionar a dependência Maven • Utilizar a anotação @EnableFeignClients <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> @EnableFeignClients @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
  • 73. Netflix Feign • Exemplo de uso com Eureka (service-id) • Utilização com URL externas @FeignClient("stores-service") public interface StoreClient { @RequestMapping(method = RequestMethod.GET, value = "/stores") List<Store> getStores(); @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json") Store update(@PathVariable("storeId") Long storeId, Store store); } @FeignClient(name = "stores-service", url = "http://example.com") public interface StoreClient {}
  • 74. Netflix Feign • Exemplo de customização de configurações @Configuration public class CustomFeignConfiguration { static final int FIVE_SECONDS = 5000; @Bean public Logger.Level feignLogger() { return Logger.Level.FULL; } @Bean public Request.Options options() { return new Request.Options(FIVE_SECONDS, FIVE_SECONDS); } } @FeignClient(value = "stores-service", configuration = CustomFeignConfiguration.class) public interface StoreClient {...}
  • 75. Netflix Feign • Configurações opcionais • Decoder: decodificação do response payload • Encoder: codificação do request payload • Logger: definição da engine de logging • Contract: configuração para utilizando Spring Cloud Contract • Feign.Builder: customização do Builder Feign • Logger.Level: definição do nível de logging • Retryer: estratégia para implementação de retry • ErrorDecoder: decodificação para erros no response • Request.Options: opções para customização das requisições
  • 76. Netflix Feign • Oferece suporte à compressão do request e response • Funcionamento similar as configurações fornecidas pelo Web server • Ótimo para melhoria de performance em requisições e respostas com muitos dados envolvidos feign.compression.request.enabled=true feign.compression.response.enabled=true feign.compression.request.mime-types=application/xml,application/json feign.compression.request.min-request-size=2048
  • 77. Netflix Feign • Oferece customização para mecanismo logging • Pode ser definido logging por Feign client definido • Ou pode ser alterado o nível de log padrão Logger.Level • NONE: Nenhuma impressão de log • BASIC: Apenas dos métodos de request, URL, e status de respostas • HEADERS: Informação básica sobre headers do request / response • FULL: Headers, body, e metadados das requisições e respostas logging.level.project.user.UserClient: DEBUG @Configuration public class FooConfiguration { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
  • 78. Netflix Feign • Oferece também uma Feign Client Builder API public interface BookClient { @RequestLine("GET /{isbn}") BookResource findByIsbn(@Param("isbn") String isbn); @RequestLine("GET") List<BookResource> findAll(); @RequestLine("POST") @Headers("Content-Type: application/json") void create(Book book); } BookClient bookClient = Feign.builder() .client(new OkHttpClient()) .encoder(new GsonEncoder()) .decoder(new GsonDecoder()) .logger(new Slf4jLogger(BookClient.class)) .logLevel(Logger.Level.FULL) .target(BookClient.class, "http://localhost:8081/api/books");
  • 79. Netflix Feign • É possível customizar diferentes Enconder e Decoder • GSON • Jackson • Sax • JAXB Feign.builder() .encoder(new GsonEncoder()) .decoder(new GsonDecoder()); Feign.builder() .encoder(new JacksonEncoder()) .decoder(new JacksonDecoder()); Feign.builder() .decoder(SAXDecoder.builder() .registerContentHandler(UserIdHandler.class) .build()); Feign.builder() .encoder(new JAXBEncoder()) .decoder(new JAXBDecoder());
  • 80. Netflix Feign • Outras configurações também são suportadas • JAX-RS • OkHttp • SLF4J Feign.builder().contract(new JAXRSContract()); Feign.builder().client(new OkHttpClient()); Feign.builder().logger(new Slf4jLogger()); interface GitHub { @GET @Path("/repos/{owner}/{repo}/contributors") List<Contributor> contributors( @PathParam("owner") String owner, @PathParam(“repo") String repo); }
  • 81. Netflix Feign • Para trabalhar com Spring MultipartFile <dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form-spring</artifactId> <version>2.1.0</version> </dependency> @Configuration class MultipartSupportConfig { @Bean @Primary @Scope("prototype") Encoder feignFormEncoder() { return new SpringFormEncoder(); } } @FeignClient(name = "file-upload-service", configuration = MultipartSupportConfig.class) interface ServiceClient { @RequestMapping(method = RequestMethod.POST, value = "/upload") ResponseEntity upload(@RequestPart(value="content") MultipartFile file) }
  • 82. Netflix Feign • Sugestão de design para implementação nas aplicações public interface UserService { @RequestMapping(method = RequestMethod.GET, value ="/users/{id}") User getUser(@PathVariable("id") long id); } @RestController public class UserRestController implements UserService { User getUser(@PathVariable("id") long id) { // Implement the REST endpoint } } @FeignClient("users") public interface UserClient extends UserService { // Empty }
  • 83. Laboratório 6 (cloud-lab06) • Implementando clientes REST com Netflix Feign
  • 87. Netflix Hystrix “Tolerância à falhas para micro-serviços“ • Implementa padrão circuit breakers • Fornece monitoramento aos serviços • Hystrix dashboard • Suporta comandos assíncronos • Utiliza diferentes thread pools • Pode implementar timeouts
  • 88. Netflix Hystrix • Circuit Breaker Pattern • Máquina de estados • Closed, Open, Half-Open • Falha não é propagada para chamada do cliente
  • 89. Netflix Hystrix • Basta adicionar a dependência Maven • Utilizar a anotação @EnableCircuitBreaker <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> @EnableCircuitBreaker @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
  • 90. • Exemplo de implementação @HystrixCommand Netflix Hystrix public class StoreIntegration { @HystrixCommand(fallbackMethod = "defaultStores") public Object getStores(Map<String, Object> parameters) { //do stuff that might fail } public Object defaultStores(Map<String, Object> parameters) { return /* something useful */; } }
  • 92. Netflix Hystrix • Suporte integrado ao Feign via Hystrix Fallback @FeignClient(name = "service-to-call", fallback = FeignClientFallback.class) public interface FeignClient { @RequestMapping(value = "/rest/do", method = RequestMethod.GET) ResponseEntity<String> doSomething(); } @Component public class FeignClientFallback implements FeignClient { @Override public ResponseEntity<String> doSomething() { return ResponseEntity.ok("fallback"); } }
  • 93. Netflix Hystrix • Configurações possíveis para Hystrix Command • Execution • execution.isolation.strategy • execution.isolation.thread.timeoutInMilliseconds • execution.timeout.enabled • execution.isolation.thread.interruptOnTimeout • execution.isolation.thread.interruptOnCancel • execution.isolation.semaphore.maxConcurrentRequests • Fallback • fallback.isolation.semaphore.maxConcurrentRequests • fallback.enabled https://github.com/Netflix/Hystrix/wiki/Configuration
  • 94. Netflix Hystrix • Configurações possíveis para Hystrix Command • Circuit Breaker • circuitBreaker.enabled • circuitBreaker.requestVolumeThreshold • circuitBreaker.sleepWindowInMilliseconds • circuitBreaker.errorThresholdPercentage • circuitBreaker.forceOpen • circuitBreaker.forceClosed • Request Context • requestCache.enabled • requestLog.enabled https://github.com/Netflix/Hystrix/wiki/Configuration
  • 95. Netflix Hystrix • Configurações possíveis para Hystrix Command • Metrics • metrics.rollingStats.timeInMilliseconds • metrics.rollingStats.numBuckets • metrics.rollingPercentile.enabled • metrics.rollingPercentile.timeInMilliseconds • metrics.rollingPercentile.numBuckets • metrics.rollingPercentile.bucketSize • metrics.healthSnapshot.intervalInMilliseconds https://github.com/Netflix/Hystrix/wiki/Configuration
  • 96. Netflix Hystrix • Outras possíveis configurações • Collapser Properties • maxRequestsInBatch • timerDelayInMilliseconds • requestCache.enabled • Thread Pool • coreSize • maximumSize • maxQueueSize • queueSizeRejectionThreshold • keepAliveTimeMinutes • allowMaximumSizeToDivergeFromCoreSize https://github.com/Netflix/Hystrix/wiki/Configuration
  • 97. Netflix Hystrix • Propriedades podem ser configuradas via anotação • @HystrixCommand e @HystrixProperty @HystrixCommand(fallbackMethod = "defaultStores", commandProperties = { @HystrixProperty(name="execution.isolation.strategy", value="THREAD"), @HystrixProperty(name="requestCache.enabled", value="false") },threadPoolProperties = { @HystrixProperty(name="coreSize", value="5"), @HystrixProperty(name="maximumSize", value="5") }) public Object getStores(Map<String, Object> parameters) { //do stuff that might fail }
  • 98. Netflix Hystrix • Propriedades podem ser configuradas via YML hystrix: command: FeignClient#doSomething(): execution: isolation: strategy: SEMAPHORE semaphore: maxConcurrentRequests: 5 fallback: isolation: semaphore: maxConcurrentRequests: 5 circuitBreaker: requestVolumeThreshold: 5 application.yml
  • 99. Netflix Hystrix • Estratégia de execução THREAD vs. SEMAPHORE
  • 100. Laboratório 7 (cloud-lab07) • Implementando circuit breakers com Netflix Hystrix
  • 102. Hystrix Dashboard • Basta adicionar a dependência Maven • Utilizar a anotação @EnableHystrixDashboard <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency> @EnableHystrixDashboard @SpringBootApplication public class HytrixDashboard { public static void main(String[] args) { SpringApplication.run(HytrixDashboard.class, args); } }
  • 103. Hystrix Dashboard • Para visualizar o dashboard basta acessar o endereço • http://localhost:[port]/hystrix
  • 104. Hystrix Dashboard • Visualização do painel de circuitos para um serviço
  • 106. Netflix Turbine • Agregador dos eventos Hystrix
  • 107. Netflix Turbine • Basta adicionar a dependência Maven • Utilizar a anotação @EnableTurbine • Pode ser utilizando em conjunto Hystrix Dashboard <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-turbine</artifactId> </dependency> @EnableTurbine @SpringBootApplication public class TurbineApplication { public static void main(String[] args) { SpringApplication.run(TurbineApplication.class, args); } }
  • 108. Netflix Turbine • É necessário configurar um cluster para visualização dos eventos gerados pelos serviços • Utiliza o registro Eureka para localização dos serviços • Basta adicionar uma configuração nas propriedades • Pode ser definido diferentes configurações de clusters (views) • http://turbine.sever/turbine.stream?cluster=<CLUSTERNAME> turbine: appConfig: service-a, service-b clusterNameExpression: "'default'" turbine: aggregator: clusterConfig: STORE appConfig: customers,stores,ui,admin
  • 109. Netflix Turbine • Para acessar o endereço do Turbine no Hystrix Dashboard • http://turbine.server:[port]/turbine.stream
  • 110. • Agregador dos eventos Hystrix assíncrono Netflix Turbine Stream
  • 111. • Utiliza um sistema de mensagens assíncrono para publicar e processar os eventos Hystrix • Pode ser utilizado com diferentes middleware • RabbitMQ, ActiveMQ, Apache Kafta, etc • Cada serviço publica seus eventos na fila processada pelo Turbine Netflix Turbine Stream
  • 112. Netflix Turbine Stream (server) • Basta adicionar a dependência Maven • É necessário também adicionar a dependência de um Stream (Rabbit, Kafta, etc) • spring-cloud-starter-stream-rabbit • Utilizar a anotação @EnableTurbineStream <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-turbine-stream</artifactId> </dependency> @EnableTurbineStream @SpringBootApplication public class TurbineStreamApplication {}
  • 113. Netflix Turbine Stream (client) • Necessário adicionar a dependência Hystrix stream • Também necessário adicionar a dependência de um Stream (Rabbit, Kafta, etc) • spring-cloud-starter-stream-rabbit • Caso necessário configurar as propriedades de configuração no Stream adicionado <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-hystrix-stream</artifactId> </dependency>
  • 114. Laboratório 8 (cloud-lab08) • Monitorando os circuitos com Hystrix Dashboard e Turbine
  • 116. Principais requisitos de segurança? • Como identificar as permissões que serão manipuladas? • Como a informação será codificada e decodificada? • Quais dados serão necessários para restrição de acesso? • Quem será responsável por armazenar e fornecer os dados de segurança? • Como identificar se a requisição não foi modificada? “Stop bad guys from accessing your resources"
  • 117. Segurança com REST • Algumas estratégias para proteger os serviços • Basic Auth (HTTP Basic) • Network Security • Certificate Based • Arquitetura RESTful não define procedimentos de segurança • HTTP methods: GET, POST, PUT, DELETE • API’s REST são tão vulneráveis quanto aplicações web tradicionais • SQL Injection, replay attacks, cross-site scripting, etc
  • 118. HTTP Basic Auth • Qual o problema com isto? • Nada, mas… • Em qual lugar você busca as credenciais? • Ok para sistemas onde todos os participantes podem compartilhar dados confidenciais de um modo seguro • Apenas suporta informações de "usuário / senha” • Apenas trabalha com autenticação • Sem distinção entre usuários e máquinas $ curl “https://$username:$password@myhost/resource"
  • 119. Network Security • Qual o problema com isto? • Nada, mas… • Chato para "debugar" e um pouco difícil de manter • Configuração fica fora do escopo de desenvolvedores • Não existe o conceito de identidade e autenticação "Security architecture based on top of web server"
  • 120. Certificate Based • Qual o problema com isto? • Nada, mas… • Não existe o conceito de identidade, apenas caso o browser tenha os certificados instalados • Obriga keystores e certificados nas aplicações e nos serviços • Não existe uma distinção muito clara quanto a usuários e máquinas $ curl -k -cert file.pem:password https://myhost:443/resource
  • 121. OAuth 2.0 • Protocolo baseado em uma especificação de padrão aberto definido pelo IETF • Habilita as aplicações acessarem e compartilharem serviços sem necessidade de compartilhar credenciais • Evita problemas com "passwords" • Essencial para mecanismo via delegação de acesso • Aplicações terceiras • Para serviços específicos • Por um tempo limitado • Pode trabalhar com revogação seletiva
  • 123. OAuth Timeline • OAuth 1.0 • Especificação core publicada em dezembro/2007 • OAuth 1.0a • Especificação revisada publicada em junho/2009 • Relacionado a correções de vulnerabilidades de segurança • OAuth 2.0 • Especificação publicada em outubro/2012 • Ser mais seguro, simples e padronizado • RFCs adicionais ainda continuam sendo trabalhadas
  • 124. OAuth 2.0 Tokens • Tipos • Bearer • Large random token • Necessita de SSL para proteção em transito • Servidor necessita gerar e armazenar este hash • Mac • Utilizado para evitar repetição • Não requer a utilização de SSL • Apenas suportado no OAuth 1.0 • Access Token • Short-lived token • Refresh Token • Long-lived token { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":“bearer", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", }
  • 127. Papéis Envolvidos • Resource Server • Proteção dos serviços • Authorization Server • Emissão de tokens de acesso para os clientes • Client Application • Solicita os serviços protegidos em nome do proprietário • Resource Owner • Concede o acesso a um serviço protegido
  • 128. OAuth 2.0 Grant Types • Authorization Code (web apps) • Confidencialidade aos clientes • Utiliza um código de autorização emitido pelo servidor • Implicit (browser-based and mobile apps) • Script heavy web apps • Usuário final pode ver o access token gerado • Resource Owner Password Credentials (user / password) • Utilizado em casos aonde o usuário confia no cliente • Expõe as credenciais do usuário para o cliente • Client Credentials (application) • Clientes recebem um token (secret) para acesso • Ideal para acesso entre aplicações
  • 129. OAuth 2.0 Grant Types • Authorization Code http://server/oauth/authorize?response_type=code&client_id=client &scope=read+write+trust &redirect_uri=http://localhost/app http://server/oauth/token?grant_type=authorization_code&code=SkiGJ8 &client_id=client &client_secret=secret &redirect_uri=http://localhost/app {"access_token":"292e1ec1-fda9-4968-b1c3-7cc0dd99483f", "token_type":"bearer", "expires_in":299997, "scope":"trust write read"}
  • 130. OAuth 2.0 Grant Types • Implicit http://server/oauth/authorize?response_type=token&client_id=client &scope=read+write+trust &redirect_uri=http://localhost/app http://localhost/app/#?access_token=292e1ec1-fda9-4968- b1c3-7cc0dd99483f
  • 131. OAuth 2.0 Grant Types • Resource Owner Password Credentials http://server/oauth/token?grant_type=password&client_id=client &client_secret=secret &username=admin &password=admin {"access_token":"292e1ec1-fda9-4968-b1c3-7cc0dd99483f", "token_type":"bearer", "expires_in":299997, "scope":"trust write read"}
  • 132. OAuth 2.0 Grant Types • Client Credentials http://server/oauth/token?grant_type=client_credentials &client_id=client&client_secret=secret {"access_token":"292e1ec1-fda9-4968-b1c3-7cc0dd99483f", "token_type":"bearer", "expires_in":299997, "scope":"trust write read"}
  • 133. OAuth 2.0 Prós & Contras • Prós • Ótima integração para acesso de aplicações à serviços oferecidos por web sites • Acesso permitido para um escopo limitado ou por tempo (duração) • Sem necessidade de compartilhamento de passwords com aplicações terceiras • Contras • Implementação pode ser um pouco complexa • Problemas de interoperabilidade • Algumas más implementações podem expor falhas de segurança
  • 134. Spring Security OAuth • Oferece implementação para OAuth (1a) e OAuth2 • Implementa os 4 tipos de authorization grants • Suporta todos os requisitos definidos pelo OAuth2 • Authorization Server • Resources Server • Client • Ótima integração com Spring MVC e JAX-RS • Configuração utilizando anotações • Integração com todo o eco-sistema Spring
  • 135. Spring Authorization Server • @EnableAuthorizationServer • Anotação utilizada para configurar OAuth2 authorization server • Existe também disponível em XML <authorization-server/> • ClientDetailsServiceConfigurer • Define os detalhes do cliente do serviço • Implementação in-memory ou via JDBC • AuthorizationServerTokenServices • Operações para gerenciar OAuth2 tokens • Tokens in-memory, JDBC ou JSON Web Token (JWT) • AuthorizationServerEndpointConfigurer • Fornece os grant types suportado pelo servidor • Todos os grant types são suportados exceto via password
  • 136. Spring Resource Server • Pode ser a mesma instância do Authorization Server • Ou então instalado como uma aplicação separada • Fornece um filtro de autenticação para aplicações web • @EnableResourceServer • Anotação utilizada para configurar OAuth2 resource server • Existe também disponível em XML <resource-server/> • Suporta controle de acesso via expressions • #oauth2.hasScope • #oauth2.clientHasRole • #oauth2.clientHasAnyRole • #oauth2.denyClient
  • 137. Spring OAuth2 Client • Cria um filtro para armazenar o contexto do request • Gerencia o redirecionamento de/para o servidor de autenticação OAuth2 • @EnableOAuth2Client • Anotação utilizada para configurar o OAuth2 client • Existe também disponível em XML <client/> • OAuth2RestTemplate • Wrapper client object para acessar os serviços
  • 138. Authorization Server @Configuration @EnableAuthorizationServer public class AuthServerConfig extends AuthorizationServerConfigurerAdapter { @Override public void configure( AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.tokenKeyAccess(“permitAll()”) .checkTokenAccess("isAuthenticated()"); } @Override public void configure( ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("SampleClientId") .secret("secret") .authorizedGrantTypes("authorization_code") .scopes("user_info") .autoApprove(true) ; } }
  • 139. Resource Server @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/users/ping").permitAll() .antMatchers("/users/current").authenticated() .anyRequest().authenticated(); } }
  • 140. Laboratório 9 (cloud-lab09) • Implementando e manipulando segurança com o protocolo OAuth2
  • 141. JSON Web Token “Padrão aberto que define uma forma compacta e auto-contida para transmitir de forma segura, informações entre duas partes“
  • 142. JSON Web Token • Basta adicionar a dependência Maven • Definir um JwtTokenStore • Configurar um JwtAccessTokenConverter • Utilizando chaves simétricas, ou assimétricas • Configurar o modelo geração e validação de JWT tokens nos serviços de autorização e recursos OAuth2 <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-jwt</artifactId> </dependency>
  • 143. JSON Web Token • Configuração utilizando modelo simétrico de chaves @Configuration public class JwtConfig { @Bean public TokenStore tokenStore() { return new JwtTokenStore(accessTokenConverter()); } @Bean public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey("123"); return converter; } }
  • 144. JSON Web Token • Modelo assimétrico de chaves (chave privada) @Configuration public class JwtConfig { //... @Bean public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource(“mykeys.jks"), "mypass".toCharArray()); converter.setKeyPair( keyStoreKeyFactory.getKeyPair("security-server")); return converter; } }
  • 145. JSON Web Token • Modelo assimétrico de chaves (chave pública) @Configuration public class JwtConfig { //... public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); Resource resource = new ClassPathResource("public.txt"); String publicKey = null; try { publicKey = IOUtils.toString(resource.getInputStream()); } catch (final IOException e) { throw new RuntimeException(e); } converter.setVerifierKey(publicKey); return converter; } }
  • 146. JSON Web Token • Para realizar a geração do par de chaves (privada e pública) pode ser utilizado keytool • Para exportar a chave pública, pode ser utilizado openssl keytool -genkeypair -alias mytest -keyalg RSA -keypass mypass -keystore mytest.jks -storepass mypass keytool -list -rfc --keystore mytest.jks | openssl x509 -inform pem -pubkey -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgIK2Wt4x2EtDl41C7vfp OsMquZMyOyteO2RsVeMLF/hXIeYvicKr0SQzVkodHEBCMiGXQDz5prijTq3RHPy2 /5WJBCYq7yHgTLvspMy6sivXN7NdYE7I5pXo/KHk4nz+Fa6P3L8+L90E/3qwf6j3 DKWnAgJFRY8AbSYXt1d5ELiIG1/gEqzC0fZmNhhfrBtxwWXrlpUDT0Kfvf0QVmPR xxCLXT+tEe1seWGEqeOLL5vXRLqmzZcBe1RZ9kQQm43+a9Qn5icSRnDfTAesQ3Cr lAWJKl2kcWU1HwJqw+dZRSZ1X4kEXNMyzPdPBbGmU6MHdhpywI7SKZT7mX4BDnUK eQIDAQAB -----END PUBLIC KEY-----
  • 147. JWT Response • Exemplo de resposta utilizando JWT { "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTMyODMxNzksInVzZXJfbmFtZSI6 InVzZXIiLCJhdXRob3JpdGllcyI6WyJVU0VSIiwiTUFOQUdFUiJdLCJqdGkiOiJkMGY5OTY2OC01Nz dkLTRkZTEtODkwYi1hNDY1MTBkZjg2YjAiLCJjbGllbnRfaWQiOiJjbGllbnQiLCJzY29wZSI6WyJv cGVuaWQiXX0.iH1pnwJZPZi05hdpY9MDGIvtx34Dj8lxc5fdU5c5NCCtUblT_L9kdZO6NaOIIZffbG zSHoyVUEZkSwkGXm6lT1jRTcOHq2khAZlwmO3hN3c1xb8bumAgmpF8fJSIKTVIkFJpbVO4uDfHSSbB m6QsTbqHkNgNwWSWbNG1n6ZlsHCcZCh37cmgbh- B4tPD9QEfH3CSI6Z7AgUbS9UCIytjm02sgxgAr3liOcykRrdcOvxgIBx_yGDvornQ5JOBVdW-TS0- uJmHe6sHCFYeBNchJhRi7xqZCMYFD6IcP4dftPupzg3IMl5oWberxhZTCCLoi18JtQyZgIgqmSlOAI q8wg", "token_type": "bearer", "expires_in": 43199, "scope": "openid", "jti": "d0f99668-577d-4de1-890b-a46510df86b0" }
  • 148. JWT Response • É possível informações extras no JWT gerado implementando customizações via TokenEnhancer public class CustomTokenEnhancer implements TokenEnhancer { @Override public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { Map<String, Object> additionalInfo = new HashMap<>(); additionalInfo.put("organization", authentication.getName() + randomAlphabetic(4)); ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation( additionalInfo); return accessToken; } }
  • 149. JWT Response • Exemplo de payload com informações extras adicionadas via TokenEnhancer { "user_name": "john", "scope": [ "foo", "read", "write" ], "organization": "johnIiCh", "exp": 1458126622, "authorities": [ "ROLE_USER" ], "jti": "e0ad1ef3-a8a5-4eef-998d-00b26bc2c53f", "client_id": "fooClientIdPassword" }
  • 150. Laboratório 10 (cloud-lab10) • Trabalhando com JSON Web Tokens
  • 151. Spring Cloud Security “Segurança aplicada para microservices" • Integração com Spring Security + OAuth2 • Proteção dos serviços com tokens (JWT) • SSO com OAuth2 e OpenID Connect • Transmissão tokens entre SSO e apps • OAuth2 + JWT + SSO ;)
  • 152. Spring Cloud Security Discovery Client Relying Party Resource Server Get an access token & an ID Token (JWT) Use an access token Authorization Server Iden.ty Provider or IDP or OpenID Provider or OP Authorization Endpoint Token Endpoint Important Stuff Userinfo Endpoint Registration Endpoint JWKS Endpoint JWKS Endpoint Validate (JWT) ID Token /.well-known /webfinger /openid-configura.on Check Session IFrame End Session Endpoint
  • 153. Spring Cloud Security • Basta adicionar a seguinte dependência Maven • Integração dos projetos Spring Security OAuth2 + JWT • spring-security-oauth2 e spring-security-jwt • Customizações de segurança as projetos Spring Cloud • OAuth2FeignRequestInterceptor • OAuth2LoadBalancerClientAutoConfiguration • AccessTokenContextRelay <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency>
  • 154. Spring Cloud Security • Propriedades customizadas para integração com serviço de recursos OAuth2 # SECURITY OAUTH2 RESOURCES (ResourceServerProperties) security.oauth2.resource.filter-order= # The order of the filter chain used to authenticate tokens. security.oauth2.resource.id= # Identifier of the resource. security.oauth2.resource.jwt.key-uri= # The URI of the JWT token. Can be set if the value is not available and the key is public. security.oauth2.resource.jwt.key-value= # The verification key of the JWT token. Can either be a symmetric secret or PEM-encoded RSA public key. security.oauth2.resource.prefer-token-info=true # Use the token info, can be set to false to use the user info. security.oauth2.resource.service-id=resource # security.oauth2.resource.token-info-uri= # URI of the token decoding endpoint. security.oauth2.resource.token-type= # The token type to send when using the userInfoUri. security.oauth2.resource.user-info-uri= # URI of the user endpoint.
  • 155. Spring Cloud Security • Propriedades customizadas para um cliente OAuth2 • PPro • Propriedades customizadas para trabalhar com SSO # SECURITY OAUTH2 CLIENT (OAuth2ClientProperties) security.oauth2.client.client-id= # OAuth2 client id. security.oauth2.client.client-secret= # OAuth2 client secret. A random secret is generated by default # SECURITY OAUTH2 SSO (OAuth2SsoProperties) security.oauth2.sso.filter-order= # Filter order to apply if not providing an explicit WebSecurityConfigurerAdapter security.oauth2.sso.login-path=/login # Path to the login page, i.e. the one that triggers the redirect to the OAuth2 Authorization Server
  • 156. Spring Cloud Security • Exemplo de proteção de um serviço com OAuth2 • Utilizando o servidor de autorização para validar os tokens @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { //... } security: sessions: stateless basic: enabled: false user: password: none oauth2: resource: preferTokenInfo: false userInfoUri: http://localhost:9999/users/current
  • 157. Spring Cloud Security • Validando o token diretamente no cliente security: sessions: stateless basic: enabled: false user: password: none oauth2: resource: jwt: keyValue: | -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo1jWPfjvJxaXCHzvClU7 uJg+6AlZ8ht1Rbr+7Wo5o+YBWgCc6lZmSv/mwxvfL/wqagQ/W756a8vUJ7qFz/k9 eBSJQSRuzJ6pT4OMMR9gbmYroh3RM/Xd5RelJgT3+OrvjAZr1pFYdAwp0q1T9XPa 6PnCXq8KhIqNPxMjcaBrOycWEgWE4g4VnnrKDLtMmEZZIc0EMv8j7womsyNkbTyl nPsbFttNwtFoTVJeqvD01Fd6ISaoOVQAUfAcxvp77B/A1g0No3GHBupEtW3Hgp2/ 80Zl0+Gwjl6Wag5Mu9H7MIUPo+4xFGAJ0uwseHiErZqdWlHIo179IacB87+9Vt0g pwIDAQAB -----END PUBLIC KEY-----
  • 158. • Suporte à definição de regras de segurança via anotações • Habilita o suporte as anotações • @PreAuthorize, @PostAuthorize, @Secured • Suportando as expressões de segurança do Spring Security • E também adicionando suporte as expressões OAuth2 Spring Cloud Security @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) public class SecurityMethodConfig extends GlobalMethodSecurityConfiguration { @Override protected MethodSecurityExpressionHandler createExpressionHandler() { return new OAuth2MethodSecurityExpressionHandler(); } }
  • 159. • OAuth2SecurityExpressionMethods • Expressões para restrição de segurança via OAuth2 • #oauth2.clientHasAnyRole('ADMIN', 'MANAGER') • #oauth2.clientHasRole('MANAGER') • #oauth2.denyOAuthClient() • #oauth2.hasAnyScope('read', 'write') • #oauth2.hasAnyScopeMatching('^abc .*', '[^a-z]{3}') • #oauth2.hasScope('read') • #oauth2.hasScopeMatching('^abc .*') • #oauth2.isClient() • #oauth2.isOAuth() • #oauth2.isUser() Spring Cloud Security
  • 160. • Integração com Feign via OAuth2FeignRequestInterceptor Spring Cloud Security @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Bean public OAuth2FeignRequestInterceptor feignRequestInterceptor( OAuth2ClientContext oAuth2ClientContext, OAuth2ProtectedResourceDetails resource) { return new OAuth2FeignRequestInterceptor( oAuth2ClientContext, resource); } }
  • 161. Laboratório 11 (cloud-lab11) • Protegendo os microservices com Spring Cloud Security
  • 162. Spring Cloud Security • É necessário proteger os demais serviços da aplicação
  • 163. Spring Cloud Security • Para proteger o Config Server • É necessário habilitar restrição de acesso no Config Server • Informar login e senha para conexão pelos clientes security: user: name: configUser password: configPassword role: SYSTEM spring: cloud: config: uri: http://localhost:8888 username: configUser password: configPassword application.yml bootstrap.yml
  • 164. Spring Cloud Security • Para proteger o Eureka Server • É necessário habilitar segurança global no serviço Eureka @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("eurekaUser").password("eurekaPassword"); } @Override public void configure(HttpSecurity http) throws Exception { http.httpBasic().and().csrf().disable() .authorizeRequests().anyRequest().authenticated(); } } eureka: client: serviceUrl: defaultZone: http://eurekaUser:eurekaPassword@localhost:8761/eureka application.yml
  • 165. Spring Cloud Security • Para proteger o Hystrix Dashboard • Necessário habilitar restrição de acesso nas propriedades • Informar login e senha para acesso ao Hystrix Dashboard • http://hystrixUser:hystrixPassword@localhost:7979/hystrix • http://hystrixUser:hystrixPassword@localhost:7979/turbine.stream security: basic: enabled: true user: name: hystrixUser password: hystrixPassword role: SYSTEM application.yml
  • 166. Laboratório 12 (cloud-lab12) • Aplicando segurança nos serviços da plataforma Spring Cloud
  • 169. API Gateway • Design pattern aplicado à microservices • Requisições podem ser apenas repassadas, ou modificadas “Single entry point for the service clients”
  • 170. Netflix Zuul “Roteamento centralizado para microservices" • Fornece único ponto de entrada para os serviços • Roteamento e balanceamento na JVM • Cria uma rota para cada serviço no Eureka • Define filtros para pontos de entrada • Similar outros roteamentos • httpd, nginx, CF go router
  • 173. Netflix Zuul • Basta adicionar a dependência Maven • Utilizar a anotação @EnableZuulProxy <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> @EnableZuulProxy @SpringBootApplication public class ZuulServer { public static void main(String[] args) { SpringApplication.run(ZuulServer.class, args); } }
  • 174. Netflix Zuul • @EnableZuulServer vs @EnableZuulProxy • @EnableZuulServer • Simples definição de um roteamento Zuul • Deve ser utilizado para customização de código de roteamento sem comportamento de proxy • “Blank” Zuul server • @EnableZuulProxy • Modelo de uso mais comum • Extensão do @EnableZuulServer • Incorpora o suporte a proxy suportando a definição de routes na configuração • Também suporta customização de código de roteamento por meio de filtros
  • 175. Netflix Zuul • Exemplo de configuração de rotas via URL zuul: routes: first: path: /first/** url: http://first.example.com second: path: /second/** url: forward:/second third: path: /third/** url: forward:/3rd legacy: path: /** url: http://legacy.example.com
  • 176. Netflix Zuul • Integração do Zuul com Eureka e Ribbon
  • 177. Netflix Zuul • Exemplo de utilização Zuul com Ribbon (serviceId) zuul: routes: aluno-service: path: /aluno/** serviceId: aluno-service disciplina-service: path: /disciplina/** serviceId: disciplina-service ribbon: eureka: enabled: false aluno-service: ribbon: listOfServers: localhost:8080,localhost:18080 disciplina-service: ribbon: listOfServers: localhost:8081,localhost:18081
  • 178. Netflix Zuul • Exemplo de utilização Zuul com Eureka (serviceId) zuul: routes: aluno-service: path: /aluno/** serviceId: aluno-service disciplina-service: path: /disciplina/** serviceId: disciplina-service eureka: client: serviceUrl: defaultZone: http://eurekaUser:eurekaPassword@localhost:8761/eureka instance: preferIpAddress: true ribbon: eureka: enabled: true
  • 179. Netflix Zuul • Por padrão Zuul ignora alguns HTTP headers • Pode-se customizar os sensitiveHeaders para definir quais headers devem ser ignorados por rota definida • Adicionalmente pode ser configurado • zuul.ignoreHeaders • Para ignorar headers globais (todos as rotas) • zuul.ignoreSecurityHeaders • True/false para ignorar os headers de segurança • https://docs.spring.io/spring-security/site/docs/current/reference/html/ headers.html#default-security-headers sensitiveHeaders: Cookie,Set-Cookie,Authorization zuul: routes: users: path: /myusers/** sensitiveHeaders: IgnoredHeader1, X-Auth-Token url: https://downstream
  • 180. Netflix Zuul • Demais configurações suportadas • zuul.max.host.connections • zuul.max.host.maxTotalConnections • zuul.max.host.maxPerRouteConnections • zuul.ribbonIsolationStrategy • zuul.prefix • zuul.stripPrefix • zuul.retryable • zuul.addProxyHeaders • zuul.addHostHeader • zuul.ignoredPatterns • zuul.ignoredServices • zuul.forceOriginalQueryStringEncoding
  • 181. Laboratório 13 (cloud-lab13) • Roteando os serviços com Netflix Zuul
  • 183. Zuul Filter • Basta implementar a interface IZuulFilter ou extender a classe ZuulFilter • Tipos de filtros • PRE • Executado antes de rotear à origem • ROUTING • Manipula a logica de roteamento do request à origem • POST • Executado após o request ter sido roteado à origem • ERROR • Executado quando algum erro acontece durante o roteamento
  • 184. Zuul Filter public class SimpleFilter extends ZuulFilter { @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { return null; } }
  • 186. Zuul Fallback class MyFallbackProvider implements ZuulFallbackProvider { @Override public String getRoute() { return "customers"; // use "*" to all routes } @Override public ClientHttpResponse fallbackResponse() { //... } } • Basta implementar um ZuulFallbackProvider • getRoute() define em qual rota será aplicado
  • 187. Zuul CORS • CORS Overview
  • 188. Zuul CORS @Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("http://localhost:8080"); config.addAllowedOrigin("http://www.example.com"); config.addAllowedHeader("*"); config.addAllowedMethod("GET"); config.addAllowedMethod("PUT"); config.addAllowedMethod("POST"); config.addAllowedMethod("DELETE"); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } • Pode ser ativado definindo um CorsFilter
  • 189. Laboratório 14 (cloud-lab14) • Implementando recursos avançados no Netflix Zuul
  • 190. Conclusões • Microservices são sistemas distribuídos • Sistemas distribuídos são essencialmente complexos • Netflix OSS define ótimas ferramentas para implementação de uma arquitetura de microservices • Spring Cloud • Ótima abstração para Netflix OSS • Fácil utilização por meio de anotações • Integrado com ecossistema Spring Boot • Enjoy it :)
  • 191. Revisão Nessa unidade você teve a oportunidade de compreender como: • Compreender as funcionalidades das plataformas Spring Cloud e Netflix OSS • Implementar um serviço de configuração centralizada utilizando Spring Cloud Config • Realizar o registro e descoberta dos serviços utilizando Netflix Eureka • Suportar tolerância à falhas e balanceamento de carga na chamada entre serviços com Netflix Ribbon • Tornar os serviços mais resilientes com a implementação de circuit breakers com Netflix Hystrix • Orquestrar a implementação de segurança entre serviços com Spring Cloud Security • Implementar um serviço de proxy e/ou roteamento utilizando Netflix Zuul
  • 192. Referências • http://projects.spring.io/spring-cloud/ • https://netflix.github.io/ • http://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/1.3.1.RELEASE/ • http://cloud.spring.io/spring-cloud-static/spring-cloud-config/1.3.1.RELEASE/ • https://github.com/Netflix/ribbon • https://github.com/Netflix/eureka • https://github.com/Netflix/Hystrix • https://ahus1.github.io/hystrix-examples/manual.html • http://cloud.spring.io/spring-cloud-security/spring-cloud-security.html • http://www.baeldung.com/spring-security-oauth-jwt • http://www.baeldung.com/sso-spring-security-oauth2 • http://blog.monkey.codes/how-to-use-jwt-and-oauth-with-spring-boot/ • http://stytex.de/blog/2016/02/01/spring-cloud-security-with-oauth2/ • https://jmnarloch.wordpress.com/2015/10/14/spring-cloud-feign-oauth2-authentication/ • http://cloud.spring.io/spring-cloud-security/spring-cloud-security.html • http://www.baeldung.com/spring-cloud-securing-services • https://github.com/Netflix/zuul • https://medium.com/netflix-techblog/announcing-zuul-edge-service-in-the-cloud-ab3af5be08ee • http://callistaenterprise.se/blogg/teknik/2015/05/20/blog-series-building-microservices/