Pedro Bertoluchi

Identidade federada com Entra ID em microsserviços .NET

OAuth2 com Entra ID é trivial no monolito e vira pesadelo distribuído quando microsserviços começam a chamar uns aos outros sem padrão definido.

8 min de leitura
Voltar para o blog

Em monolito, integrar Entra ID é meia tarde: AddAuthentication, AddMicrosoftIdentityWebApi, registrar o app no portal, pronto. Em microsserviços, a mesma operação vira um campo minado de tokens com audience errado, claims que somem na segunda chamada, loops de validação entre APIs internas e um custo de latência que ninguém previu. A causa raiz é quase sempre a mesma: tratar cada serviço como se fosse o monolito e deixar o token do usuário viajar livre pela malha.

A primeira regra é não compartilhar o mesmo token entre serviços. O token emitido para o frontend tem audience da API pública. Repassá-lo para uma API interna que valida o mesmo audience é abrir a porta lateral: qualquer serviço comprometido com acesso ao token tem o mesmo escopo do usuário. O padrão correto é cada API ter seu próprio audience registrado no Entra ID, e a transição entre serviços passar por troca explícita de token, não por encaminhamento.

O gateway carrega o peso. Ele valida o token do usuário, extrai as claims que importam, faz claims transformation, e emite um token interno assinado por chave própria com audience do serviço destino e tempo de vida curto. O serviço interno confia apenas nesse token interno, nunca no token do Entra direto. Isso elimina o loop clássico em que serviço A chama serviço B que chama serviço A de novo com o mesmo token, validando três vezes contra o tenant e acumulando latência inútil.

Propagação de contexto entre serviços usa DelegatingHandler com correlation ID e tenant ID no header, não claims do JWT. Claims são para autorização local; contexto é para rastreabilidade. Misturar as duas coisas força o serviço de destino a confiar em informação que não veio do emissor original. OpenTelemetry com baggage resolve a parte de propagação e ainda entrega traço distribuído de graça, o que é o segundo benefício mais subestimado dessa arquitetura.

Comunicação máquina-a-máquina entre serviços internos usa client credentials flow, não impersonation. Cada serviço tem sua própria identidade no Entra, com permissões mínimas registradas no manifesto da API destino. O refresh é gerenciado pelo MSAL com cache distribuído (Redis, não memória local), porque cache local em microsserviço com escala horizontal força refresh redundante em cada réplica e estoura o rate limit do Entra antes do esperado.

Refresh do token do usuário é responsabilidade do BFF, não dos serviços internos. O serviço interno recebe um token de curta duração e falha rápido se expirou; o BFF faz o silent refresh e retenta. Distribuir lógica de refresh por todo serviço da malha é a origem mais comum de race condition em produção: dois serviços tentando refresh ao mesmo tempo, ambos invalidando o anterior, usuário deslogado do nada. Centralizar essa responsabilidade no edge custa uma camada e elimina uma classe inteira de bug que só aparece em carga real.

Tags

  • #dotnet
  • #azure
  • #seguranca
  • #entra-id

Vamos conversar sobre o seu próximo projeto.

Descreva o desafio em poucas linhas. Em até 1 dia útil eu retorno com uma avaliação técnica e os próximos passos.