API Gateway

O que é?

O Cloudsupport API Gateway é um projeto de container Docker, configurável por YAML, baseado no framework Spring Cloud Gateway, pronto para produção.

Vantagens

Funcionalidades em destaque:

  • Non-blocking IO e backpressure-ready TCP, devido ao framework Spring WebFlux e ao servidor Reactor Netty.

  • Conformidade com OIDC/JWT, provida pelo Spring Security, permitindo que o Gateway atue como um Resource Server e/ou OAuth2 Client / OIDC Relying Party.

  • Controle de taxa, ou Rate Limiting, via Redis.

  • Caching de corpo e de cabeçalhos HTTP, fornecido pelo Caffeine.

  • Circuit Breaker, implementado pela biblioteca Resilience4j.

  • Observabilidade, incluindo Spring Boot Actuator e endpoint de métricas Prometheus.

  • Suporte a WebSocket e gRPC, nativo to Spring Cloud Gateway.

  • Enriquecimento e relaying de UserDetails, provido pelo Cloudsupport, que viabiliza offloading de OIDC nos microsserviços protegidos pelo Gateway.

Visão Geral

O API Gateway tem a função principal de garantir a segurança dos microsserviços no que se refere ao controle de autenticação de endpoints e proteção contra os ataques mais comuns. Esses recursos são providos pelo Spring Cloud Gateway em conjunto com o Spring Security.

Ainda, o API Gateway pode assumir a função de enriquecimento de dados de autenticação dentro do ambiente do backend, de maneira segura e global, sem onerar os microsserviços com essa tarefa. Esse recurso é provido pelo Cloudsupport, não sendo nativo do Spring Cloud Gateway.

O diagrama abaixo mostra uma implantação do API Gateway e exemplifica sua operação:

API Gateway

(1) e (2) representam o fluxo de autenticação baseado em “Authorization Code” e obtenção pela aplicação cliente (frontend) dos tokens OIDC (ID Token, User Info, Access Token e Refresh Token).

(3) representa uma requisição webservice acompanhada de token de autorização JWT (JSON Web Token), assinado e criptografado. O Gateway atua como Resource Server no sentido de validar o JWT e impedir acessos não autorizados aos microsserviços. Padrões JWS (JSON Web Signature) e JWE (JSON Web Encryption) são utilizados pelo Gateway para validação do JWT.

(4) representa um enriquecimento do request com atributos do usuário, sendo um recurso complementar oferecido pelo Cloudsupport. Pode ser utilizado para complementação com dados sensíveis, oferecendo uma alternativa mais conveniente e segura em comparação à exposição através de ID Token, User Info ou Access Token.

(5) representa o forwarding do request autenticado para o backend, podendo incluir o enriquecimento citado.

A aplicação de API Gateway é desejada, porém não obrigatória. Sua utilidade deve ser analisada conforme o contexto de cada projeto. Ressalta-se que além do papel de offloading da validação da autorização, o API Gateway oferece recursos adicionais como rate limiting e cache. Ainda, com API Gateway tem-se um ponto centralizado de observabilidade quanto à análise do tráfego de consumo de webservices. O API Gateway suporta escalabilidade horizontal, sem restrições.

No que tange OIDC e segurança, como validação do Access Token e enriquecimento dos atributos do usuário, o microsserviço pode implementar essas funções através da configuração do Spring Security diretamente no microsserviço. Este cenário pode ser conveniente quando há limitações de recursos computacionais.

Algumas notas relevantes sobre o padrão OIDC estão dispostas ao final deste documento.

Instalando o Gateway

Consulte as instruções de como implantar o Gateway no arquivo README.md, constante no repositório do projeto.

A seção seguinte contém a documentação sobre a configuração do container.

Configurando o Gateway

O Gateway é configurado por arquivo properties ou yml na forma de profile do Spring Boot. Consulte a documentação do Spring Boot sobre as maneiras possíveis de informar profile.

O Gateway acompanha um exemplo de configuração, composto pelos seguintes arquivos:

  • application.properties: Configuração raiz do Spring Boot. Este arquivo faz a importação dos arquivos seguintes.

  • application-demo-server.yml: Configurações básicas do servidor, como porta TCP, porta do Actuator e CORS.

  • application-demo-routes.yml: Mapeia endpoints para os três cenários de teste:

    • Endpoints públicos

    • Endpoints autenticados via SSO (o Gateway atua como Client do OIDC)

    • Endpoints autenticados por token JWT (o Gateway atua como Resource Server do OAuth2), sendo este o caso típico de aplicação de API Gateway para microsserviços

  • application-demo-oauthclient.yml: Configurações do Gateway para quando ele atua como Client do OIDC. Essas configurações são utilizadas em endpoints disponibilizados pelo próprio Gateway e que requerem autenticação no SSO do OpenID Connect.

  • application-demo-oauthresourceserver.yml: Configurações do Gateway para quando ele atua como Resource Server do OAuth2. Essas configurações são utilizadas em endpoints roteados pelo Gateway e que requerem validação de token OAuth2/JWT.

Para configuração mais avançada do Gateway, além dos exemplos nos YAMLs que acompanham o projeto, consulte:

As configurações específicas do Cloudsupport estão descritas nas seções seguintes.

CORS

O Cloudsupport permite a configuração de CORS via YAML, na propriedade cloudsupport.security.cors. A configuração padrão, se não informada, é:

cloudsupport:
  security:
    cors:
      allowed-origins:
        - "*"
      allowed-methods:
        - "GET"
        - "POST"
      path: "/**"

URLs Públicas

O Cloudsupport permite a configuração de URLs públicas via YAML, na propriedade cloudsupport.security.permitted-ant-patterns.

Sugestão de configuração:

cloudsupport:
  security:
    permitted-ant-patterns:
      - "/actuator/**"
      - "/oauth2/**"
      - "/login/**"

Nota: Recomenda-se configurar porta distinta para o Actuator (vide documentação do Spring Boot).

UserDetails

O Cloudsupport enriquecerá o AuthenticationToken do Spring Security com UserDetails se a propriedade abaixo estiver configurada:

cloudsupport:
  security:
    oauth2:
      resourceserver:
        jwt:
          user-details-uri: https://endpointToDetails

O endpoint deve retornar JSON.

O retorno será carregado na forma de claims Map<String,String> no JsonUserDetails.

O endpoint receberá como parâmetro do JWT: user-details-uri?jwt=<base64>.

O enriquecimento ocorre apenas quando o Gateway atua como Resource Server, ou seja, quando há presença de token JWT no request.

UserDetailsRelay Gateway Filter

O UserDetails, uma vez carregado no Spring Security conforme descrito acima, poderá ser propagado na forma de header HTTP pelo filtro UserDetailsRelay do Cloudsupport. O nome do header por padrão é X-User-Details.

spring:
  cloud:
    gateway:
      routes:
        - id: routeId
          #...
          filters:
            - RemoveRequestHeader=X-User-Details
            - UserDetailsRelay=X-User-Details

O UserDetails será propagado como JSON em Base64.

O filtro RemoveRequestHeader no exemplo acima evita ataque por injeção do header X-User-Details. Recomenda-se configurá-lo como global.

LogAuth Gateway Filter

O filtro LogAuth, do Cloudsupport, imprime via Logger SLF4j os atributos do objeto Authentication do Spring Security, permitindo depuração do fluxo do Resource Server. O nível do log é o parâmetro único, por padrão “DEBUG”:

spring:
  cloud:
    gateway:
      routes:
        - id: routeId
          #...
          filters:
            - LogAuth=INFO