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”
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
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
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
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
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/
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
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);
}
}
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;
}
}
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
}
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>
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
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();
}
}
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-----
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);
}
}
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
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
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
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
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
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