Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

Workshop Microservices - Microservices com Spring Cloud e Netflix OSS

1.709 visualizaciones

Publicado el

Treinamento voltado para arquitetos de software, líderes de equipe, desenvolvedores em geral...

Publicado en: Tecnología
  • Sé el primero en comentar

Workshop Microservices - Microservices com Spring Cloud e Netflix OSS

  1. 1. Workshop Microservices Microservices com Spring Cloud e Netflix OSS
  2. 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. 3. Agenda • Spring Cloud e Netflix OSS • Spring Cloud Config • Netflix Eureka • Netflix Ribbon e Feign • Netflix Hystrix • Spring Cloud Security • Netflix Zuul
  4. 4. Arquitetura Microservices
  5. 5. Microservices • Quais os principais desafios? • Gerenciamento de configuração • Registro e descoberta dos serviços • Roteamento • Balanceamento de carga • Tolerância à falhas
  6. 6. • Eureka • Hystrix • Ribbon • Zuul • + muitos outros… • API • Routing / Health check • Microservices • Logging • Data Management
  7. 7. 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”
  8. 8. Spring Cloud • Principais Componentes
  9. 9. Spring Cloud
  10. 10. 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
  11. 11. 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>
  12. 12. 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
  13. 13. Spring Cloud + Netflix OSS
  14. 14. Gerenciamento de Configuração
  15. 15. 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
  16. 16. Spring Cloud Config • Serviço de configuração centralizado
  17. 17. 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); } }
  18. 18. 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"
  19. 19. Spring Cloud Config (server) @SpringBootApplication @EnableConfigServer public class ConfigServer {...} spring.cloud.config.git.uri: https://github.com/... ConfigServer.java application.yml
  20. 20. 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*
  21. 21. 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
  22. 22. 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
  23. 23. 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
  24. 24. Spring Cloud Config (client)
  25. 25. 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
  26. 26. 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
  27. 27. Laboratório 1 (cloud-lab01) • Centralizando a configuração com Spring Cloud Config
  28. 28. Spring Cloud Config + Bus
  29. 29. • Exemplo da arquitetura de replicação de configuração utilizada Spring Cloud Config + Bus
  30. 30. • 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
  31. 31. 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
  32. 32. 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
  33. 33. Spring Cloud Config + Bus • Configuração do Webhook no repositório Git
  34. 34. Laboratório 2 (cloud-lab02) • Replicando a configuração centralizada com Spring Cloud Config Bus
  35. 35. Registro e Descoberta de Serviços
  36. 36. Registro e Descoberta de Serviços
  37. 37. Registro e Descoberta de Serviços
  38. 38. Registro e Descoberta de Serviços Service Register Health Check
  39. 39. 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
  40. 40. 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); } }
  41. 41. 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/
  42. 42. Netflix Eureka (server)
  43. 43. Netflix Eureka @SpringBootApplication @EnableEurekaServer public class EurekaServer {...} EurekaServer.java
  44. 44. 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); } }
  45. 45. 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
  46. 46. 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); // ... } }
  47. 47. 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); // ... } }
  48. 48. Laboratório 3 (cloud-lab03) • Registrando e descobrindo serviços com Netflix Eureka
  49. 49. Netflix Eureka
  50. 50. Netflix Eureka
  51. 51. 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
  52. 52. Netflix Eureka
  53. 53. Laboratório 4 (cloud-lab04) • Ativando o suporte à replicação com Netflix Eureka
  54. 54. Balanceamento de Carga
  55. 55. Balanceamento de Carga
  56. 56. 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
  57. 57. Netflix Ribbon
  58. 58. 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>
  59. 59. 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
  60. 60. 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
  61. 61. Netflix Ribbon • Configurações possíveis para IRule • AvailabilityFilteringRule • ClientConfigEnabledRoundRobinRule • RandomRule • ResponseTimeWeightedRule • RetryRule • RoundRobinRule • WeightedResponseTimeRule • ZoneAvoidanceRule
  62. 62. Netflix Ribbon • Configurações possíveis para ILoadBalancer • BaseLoadBalancer • DynamicServerListLoadBalancer • NoOpLoadBalancer • ZoneAwareLoadBalancer • Configurações possíveis para IPing • DummyPing • NoOpPing • PingConstant
  63. 63. 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 } }
  64. 64. 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); } }
  65. 65. 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
  66. 66. 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); } }
  67. 67. Laboratório 5 (cloud-lab05) • Implementando balanceamento de carga e tolerância à falhas com Netflix Ribbon
  68. 68. 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"
  69. 69. 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); } }
  70. 70. 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 {}
  71. 71. 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 {...}
  72. 72. 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
  73. 73. 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
  74. 74. 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; } }
  75. 75. 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");
  76. 76. 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());
  77. 77. 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); }
  78. 78. 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) }
  79. 79. 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 }
  80. 80. Laboratório 6 (cloud-lab06) • Implementando clientes REST com Netflix Feign
  81. 81. Tolerância à Falhas
  82. 82. Tolerância à Falhas
  83. 83. Tolerância à Falhas
  84. 84. 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
  85. 85. Netflix Hystrix • Circuit Breaker Pattern • Máquina de estados • Closed, Open, Half-Open • Falha não é propagada para chamada do cliente
  86. 86. 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); } }
  87. 87. • 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 */; } }
  88. 88. Netflix Hystrix
  89. 89. 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"); } }
  90. 90. 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
  91. 91. 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
  92. 92. 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
  93. 93. 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
  94. 94. 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 }
  95. 95. 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
  96. 96. Netflix Hystrix • Estratégia de execução THREAD vs. SEMAPHORE
  97. 97. Laboratório 7 (cloud-lab07) • Implementando circuit breakers com Netflix Hystrix
  98. 98. Hystrix Dashboard
  99. 99. 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); } }
  100. 100. Hystrix Dashboard • Para visualizar o dashboard basta acessar o endereço • http://localhost:[port]/hystrix
  101. 101. Hystrix Dashboard • Visualização do painel de circuitos para um serviço
  102. 102. Hystrix Dashboard
  103. 103. Netflix Turbine • Agregador dos eventos Hystrix
  104. 104. 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); } }
  105. 105. 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
  106. 106. Netflix Turbine • Para acessar o endereço do Turbine no Hystrix Dashboard • http://turbine.server:[port]/turbine.stream
  107. 107. • Agregador dos eventos Hystrix assíncrono Netflix Turbine Stream
  108. 108. • 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
  109. 109. 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 {}
  110. 110. 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>
  111. 111. Laboratório 8 (cloud-lab08) • Monitorando os circuitos com Hystrix Dashboard e Turbine
  112. 112. Segurança Closed ClosedOpen Autenticação Autorização
  113. 113. 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"
  114. 114. 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
  115. 115. 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"
  116. 116. 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"
  117. 117. 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
  118. 118. 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
  119. 119. Quem utiliza OAuth
  120. 120. 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
  121. 121. 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", }
  122. 122. OAuth 2.0 Flow
  123. 123. OAuth 2.0 Flow
  124. 124. 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
  125. 125. 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
  126. 126. 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"}
  127. 127. 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
  128. 128. 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"}
  129. 129. 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"}
  130. 130. 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
  131. 131. 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
  132. 132. 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
  133. 133. 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
  134. 134. 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
  135. 135. 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) ; } }
  136. 136. 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(); } }
  137. 137. Laboratório 9 (cloud-lab09) • Implementando e manipulando segurança com o protocolo OAuth2
  138. 138. JSON Web Token “Padrão aberto que define uma forma compacta e auto-contida para transmitir de forma segura, informações entre duas partes“
  139. 139. 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>
  140. 140. 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; } }
  141. 141. 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; } }
  142. 142. 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; } }
  143. 143. 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-----
  144. 144. 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" }
  145. 145. 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; } }
  146. 146. 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" }
  147. 147. Laboratório 10 (cloud-lab10) • Trabalhando com JSON Web Tokens
  148. 148. 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 ;)
  149. 149. 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
  150. 150. 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>
  151. 151. 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.
  152. 152. 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
  153. 153. 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
  154. 154. 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-----
  155. 155. • 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(); } }
  156. 156. • 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
  157. 157. • 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); } }
  158. 158. Laboratório 11 (cloud-lab11) • Protegendo os microservices com Spring Cloud Security
  159. 159. Spring Cloud Security • É necessário proteger os demais serviços da aplicação
  160. 160. 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
  161. 161. 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
  162. 162. 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
  163. 163. Laboratório 12 (cloud-lab12) • Aplicando segurança nos serviços da plataforma Spring Cloud
  164. 164. Roteamento
  165. 165. Roteamento
  166. 166. API Gateway • Design pattern aplicado à microservices • Requisições podem ser apenas repassadas, ou modificadas “Single entry point for the service clients”
  167. 167. 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
  168. 168. Netflix Zuul
  169. 169. Netflix Zuul
  170. 170. 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); } }
  171. 171. 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
  172. 172. 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
  173. 173. Netflix Zuul • Integração do Zuul com Eureka e Ribbon
  174. 174. 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
  175. 175. 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
  176. 176. 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
  177. 177. 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
  178. 178. Laboratório 13 (cloud-lab13) • Roteando os serviços com Netflix Zuul
  179. 179. Zuul Filter • Lifecycle
  180. 180. 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
  181. 181. 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; } }
  182. 182. Zuul Fallback
  183. 183. 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
  184. 184. Zuul CORS • CORS Overview
  185. 185. 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
  186. 186. Laboratório 14 (cloud-lab14) • Implementando recursos avançados no Netflix Zuul
  187. 187. 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 :)
  188. 188. 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
  189. 189. 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/

×