Identity Server

O Identity Server é um framework que centraliza a autenticação de aplicações e APIs em um único serviço, usando os protocolos OpenID Connect e OAuth 2.0. Com o crescimento de aplicações e APIs distribuídas, concentrar o processo de autenticação em um serviço pode ser uma ótima ideia para o seu produto.

Neste artigo, vamos entender o propósito e os fundamentos do IdentityServer4, a versão para ASP.NET Core usada nesta série. Em seguida, vamos ver os protocolos envolvidos, a terminologia e as especificações suportadas.

Índice da série

Este conteúdo faz parte de uma pequena série. Por isso, vale conhecer a ordem dos artigos:

O que é o Identity Server

O Identity Server, ou servidor de identidade, é um framework que implementa os protocolos OpenID Connect e OAuth 2.0 para o ASP.NET Core. Na prática, ele roda como um middleware dentro de uma aplicação ASP.NET Core e transforma essa aplicação em um servidor de tokens.

A documentação da Microsoft sobre autenticação descreve o IdentityServer como um framework open source para diversos cenários de autenticação e autorização. Entre eles está a emissão de tokens de segurança para usuários locais do ASP.NET Core Identity.

A seguir, vamos passar pelas principais funcionalidades que ele oferece.

Autenticação como serviço com o Identity Server

O Identity Server centraliza a autenticação de múltiplas aplicações e serviços. Por exemplo, suas apps ASP.NET, Blazor, Angular, React e Flutter podem usar o mesmo ponto de login.

Assim, a lógica de login, a política de senhas e as telas de acesso ficam em um único lugar. Com isso, cada aplicação deixa de reimplementar o mesmo processo.

Single Sign On

O IS (Identity Server) fornece um serviço de SSO (Single Sign On), ou login único, para todas as suas aplicações. Em outras palavras, o usuário faz login uma vez e acessa as demais aplicações sem digitar a senha de novo.

O mesmo vale para o logout. Quando o usuário sai de uma aplicação, o servidor pode encerrar a sessão em todas as outras.

Identity Server para SPAs, apps mobile e APIs

Como o IS trabalha facilmente com access tokens (tokens de acesso), ele cobre bem as necessidades das SPAs. Esse é o caso de aplicações em Angular, React, Vue e Blazor.

Assim como nas SPAs, as aplicações móveis realizam a autenticação utilizando access tokens. Nesse cenário, o Identity Server também atende bem.

Caso seja necessário autenticar uma API diante de outra, essa comunicação também pode usar access tokens. Novamente, o Identity Server entra como a autoridade que emite e valida esses tokens.

É importante lembrar que o IS utiliza o protocolo OpenID Connect, que é um padrão aberto. Portanto, suas APIs em Node, Go, Python ou qualquer outra linguagem ou framework podem se comunicar com ele.

ASP.NET Identity

Por fim, mas não menos importante, as aplicações web com ASP.NET renderizadas no servidor normalmente usam autenticação via cookies e o ASP.NET Identity. Nesse caso, podemos conectar o Identity Server a essas aplicações facilmente.

Para entender melhor essa integração, vale revisar três conceitos que aparecem o tempo todo.

Autenticação via token: o cliente envia usuário e senha ao servidor, que valida as informações e gera um token assinado com uma chave que só o servidor conhece. A partir daí, o cliente envia esse token nas próximas requisições.

JWT: é a sigla para JSON Web Token, o formato de token mais comum nesse cenário. Ele possui três partes (cabeçalho, conteúdo e assinatura), e as duas primeiras são JSON codificado em Base64Url, por isso qualquer pessoa consegue ler o conteúdo, mas não alterá-lo sem invalidar a assinatura.

Autenticação via cookies: em APIs, normalmente não mantemos sessão, enquanto nas aplicações ASP.NET renderizadas no servidor é comum usar cookies. Ou seja, o servidor gera um valor de autenticação e o navegador o armazena e reenvia a cada requisição.

Em ambos os casos, token ou cookie, as informações do usuário viajam em cada requisição. Se quiser se aprofundar no formato do token, confira o artigo o que é JWT.

Federation Gateway

O IS permite utilizar serviços externos para validar a identidade, como Facebook, Google e Microsoft, dentre outros. Além disso, podemos combinar nossa autenticação interna com essas autenticações externas.

Antes de seguir, vale separar dois conceitos. Autenticação diz quem o usuário é, enquanto autorização diz o que o usuário pode fazer.

Para autenticar, podemos nos basear em informações internas, como o nosso banco de dados, ou delegar o processo para autoridades externas. Em ambos os casos, uma autoridade em que confiamos endossa que o usuário é verdadeiro:

  • "balta.io, me confirma se xpto@balta.io é realmente o André Baltieri"
  • "Facebook, me confirma se xpto@balta.io é realmente o André Baltieri"
  • "Microsoft, me confirma se xpto@balta.io é realmente o André Baltieri"

A pergunta é sempre a mesma. Só muda a autoridade, ou seja, a entidade em que confiamos, para quem perguntamos.

Outras considerações

O IdentityServer4 também é muito customizável, então podemos alterar boa parte do seu comportamento. Além disso, ele é open source, sem custo de licença, e está no mercado há bastante tempo, o que garante boa maturidade.

Vale um aviso importante, porém. O IdentityServer4 deixou de receber suporte no fim de 2022, e a evolução do projeto continuou como Duende IdentityServer, que, segundo a Microsoft, pode exigir licença paga para uso em produção.

Autenticação no cenário atual e o papel do Identity Server

Um cenário comum hoje, embora não seja uma regra, envolve diversas aplicações e APIs conversando com nossos servidores, como mostra a imagem abaixo.

Diagrama de arquitetura com navegador, aplicação web, aplicações nativas e servidores externos acessando APIs que também se comunicam entre si
Cenário atual de autenticação. Fonte: documentação oficial do IdentityServer4.

Nesse cenário, o navegador se comunica com a aplicação web renderizada no servidor. Da mesma forma, uma página dessa aplicação pode fazer uma requisição para uma API, também no servidor.

Note que, internamente, também existe comunicação entre a aplicação web e qualquer outra API de que ela precise para compor uma resposta.

Por fim, aplicações nativas e outros servidores, como serviços externos, também consomem a nossa API. Por sua vez, tanto a API quanto a aplicação web usam outras APIs internas.

Inicialmente, o cenário pode parecer confuso. Contudo, pense que esses itens agem de forma independente e podem se comunicar entre si.

Na primeira camada, onde ficam as aplicações (navegador, desktop, mobile e até APIs externas), precisamos implementar autenticação. Afinal, muitos usuários só podem ver os próprios dados ou não podem acessar determinadas informações.

A proposta do Identity Server é justamente centralizar esse recurso comum entre as aplicações, a autenticação. Imagine precisar escrever um processo de login para cada uma delas.

Diagrama reestruturado em que o Identity Server centraliza a autenticação das aplicações e a emissão de tokens para as APIs usando OpenID Connect e OAuth 2.0
O mesmo cenário reorganizado em torno de um servidor de autenticação. Fonte: documentação oficial do IdentityServer4.

Essa seria uma visão do mesmo diagrama de forma mais estruturada. Nela, um servidor de autenticação centraliza o processo, e os protocolos como OAuth 2.0 organizam a comunicação.

Protocolos de autenticação

A documentação da Microsoft sobre aplicações cloud native cita três protocolos comuns de autenticação, o SAML2p, o WS-Federation e o OpenID Connect. Já a comunicação com APIs normalmente usa o OAuth 2.0 e seus tokens de segurança.

SAML

O SAML (ou SAML2p) é um protocolo de autenticação muito conhecido e usado. Na verdade, ele ainda é bastante comum em ambientes corporativos, mas o OpenID Connect vem dominando as aplicações modernas.

WS-Federation

Assim como o SAML, o WS-Federation também é um protocolo de autenticação. Ele teve muita força na época do WCF, porém hoje o OpenID Connect está muito à sua frente.

OpenID Connect

O OpenID Connect é o mais novo entre os protocolos citados, embora existam outros. Por isso, muita gente o considera o presente e o futuro da autenticação.

Ele nasceu pensando nos cenários atuais, com múltiplas aplicações, serviços e até autenticações externas. Atualmente, ele é a recomendação para autenticação em aplicações modernas.

OAuth 2.0

Nossas aplicações têm duas formas de se comunicar com APIs de forma segura. A primeira usa uma identidade própria da aplicação, e a segunda delega a identidade do usuário.

Às vezes precisamos usar os dois modos, e o OAuth entra justamente nesse ponto. Ele é um protocolo que permite às aplicações requisitar um token a um serviço de tokens e utilizá-lo nas suas requisições.

Como comentamos antes, isso reduz código e complexidade, porque concentra a autenticação em um único ponto.

O OpenID Connect e o OAuth 2.0 são bem parecidos, mas têm responsabilidades diferentes. Na verdade, o OpenID Connect é uma camada de autenticação sobre o OAuth 2.0, e a combinação dos dois une autenticação e acesso a APIs em um único protocolo.

Dessa forma, essa combinação cobre tudo o que vimos na imagem anterior, com autenticação para aplicações desktop, web, mobile e APIs.

Identity Server no ASP.NET Core

O Identity Server é uma implementação do OpenID Connect e do OAuth 2.0 no formato de middleware para o ASP.NET Core. Basicamente, qualquer lógica dentro das APIs ou aplicações não afeta a implementação do servidor, porque ele abstrai apenas a parte de autenticação.

Esse middleware expõe endpoints padronizados. Entre eles estão o de autorização (autenticar o usuário), o de token, o de descoberta (metadados do servidor), o de informações do usuário, o de introspecção, o de revogação e o de encerramento de sessão.

Na aplicação, a configuração acontece no pipeline do ASP.NET Core. O exemplo abaixo mostra a estrutura básica de um servidor com IdentityServer4 no modelo de Startup da época, com clientes, recursos e escopos em memória:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddIdentityServer()
            // Credencial de assinatura apenas para desenvolvimento
            .AddDeveloperSigningCredential()
            .AddInMemoryIdentityResources(Config.IdentityResources)
            .AddInMemoryApiScopes(Config.ApiScopes)
            .AddInMemoryClients(Config.Clients);
    }

    public void Configure(IApplicationBuilder app)
    {
        // Adiciona os endpoints do OpenID Connect e do OAuth 2.0 ao pipeline
        app.UseIdentityServer();
    }
}

A ordem importa nesse pipeline. Segundo a documentação da Microsoft, o UseIdentityServer precisa vir antes do framework de interface que implementa a tela de login.

O passo a passo completo, com templates e o primeiro cliente, está no próximo artigo da série, criando seu primeiro Identity Server. Além disso, se você quer comparar com a validação de tokens direto na API, veja autenticação e autorização com JWT e Bearer no ASP.NET 7.

Terminologia do Identity Server

Antes de criar o primeiro servidor, é importante dominar alguns termos que aparecem em toda a documentação.

Usuário ou user: o usuário é a pessoa que utiliza um cliente registrado para obter acesso a um recurso.

Cliente ou client: o cliente é o software que requisita tokens ao Identity Server, seja para autenticar pessoas, seja para acessar outros serviços. Um cliente deve estar registrado no servidor de identidade antes de requisitar um token.

Recursos ou resources: os recursos são as informações que queremos proteger com o servidor de identidade. Todo recurso tem um nome único, e os clientes usam esse nome para indicar qual recurso querem acessar.

Identity data: as informações de identidade também recebem o nome de claims. Elas se referem ao usuário, como nome ou endereço de e-mail.

Identity token: o identity token é o resultado de um processo de autenticação. Ele contém o mínimo de identificação possível sobre o usuário, o chamado subject ou subject claim, além de informações sobre como e quando ele se autenticou.

Access token: o access token permite o acesso a um recurso. Os clientes requisitam tokens de acesso e os encaminham a cada requisição para as APIs.

Esses tokens contêm informações sobre o cliente e sobre o usuário, quando houver um. Então, a API usa essas informações para autorizar o acesso aos seus dados.

Especificações suportadas pelo Identity Server

O IdentityServer4 implementa um conjunto amplo de especificações. Portanto, ele se integra a clientes e bibliotecas de qualquer plataforma que sigam esses padrões.

Especificações do OpenID Connect

Especificação Para que serve
OpenID Connect Core 1.0 Núcleo do protocolo de autenticação sobre o OAuth 2.0
OpenID Connect Discovery 1.0 Publicação dos metadados e endpoints do servidor
OpenID Connect Session Management 1.0 Acompanhamento da sessão do usuário no servidor
OpenID Connect Front-Channel Logout 1.0 Logout das aplicações por meio do navegador
OpenID Connect Back-Channel Logout 1.0 Logout por comunicação direta entre servidores

Especificações do OAuth 2.0

Especificação Para que serve
OAuth 2.0 (RFC 6749) Framework base de autorização
OAuth 2.0 Bearer Token Usage (RFC 6750) Envio de tokens bearer nas requisições
OAuth 2.0 Multiple Response Types Combinação de tipos de resposta no fluxo
OAuth 2.0 Form Post Response Mode Retorno da resposta via POST de formulário
OAuth 2.0 Token Revocation (RFC 7009) Revogação de tokens
OAuth 2.0 Token Introspection (RFC 7662) Validação de tokens junto ao servidor
Proof Key for Code Exchange (RFC 7636) Proteção do fluxo de código, o PKCE
JSON Web Tokens for Client Authentication (RFC 7523) Autenticação de clientes com JWT
OAuth 2.0 Device Authorization Grant (RFC 8628) Login em dispositivos sem teclado
OAuth 2.0 Mutual TLS (RFC 8705) Autenticação de clientes e tokens vinculados a certificados
JWT Secured Authorization Request Requisição de autorização assinada como JWT

Na prática, isso significa que o servidor suporta fluxos modernos, como o PKCE para SPAs e apps móveis. Da mesma forma, o Device Authorization Grant atende dispositivos sem teclado, como TVs.

Quando usar o Identity Server

O Identity Server faz mais sentido quando você tem várias aplicações e APIs que precisam compartilhar a mesma identidade. Além disso, ele brilha quando você precisa de SSO, de login social e de controle total sobre o servidor.

Por outro lado, para uma única API simples, validar um JWT diretamente pode bastar. Nesse caso, um servidor de identidade dedicado adiciona infraestrutura sem trazer muito ganho.

Também existem alternativas no ecossistema .NET. A Microsoft lista opções como OpenIddict e Keycloak, de código aberto, além de serviços gerenciados como Microsoft Entra ID, Auth0 e Okta.

Portanto, a escolha depende do número de aplicações, da necessidade de controle e do orçamento disponível para licenças ou serviços gerenciados.

Conclusão

O Identity Server centraliza a autenticação de aplicações web, SPAs, apps móveis e APIs em um único servidor baseado em OpenID Connect e OAuth 2.0. Com isso, você evita reescrever o login em cada aplicação e ganha SSO, federação com provedores externos e tokens padronizados.

Neste artigo, vimos o que é o Identity Server, os protocolos de autenticação, a terminologia e as especificações suportadas. No próximo passo da série, vamos colocar a mão no código e criar o primeiro servidor de identidade.

FAQ

O que é o Identity Server?

É um framework para ASP.NET Core que implementa OpenID Connect e OAuth 2.0. Ele centraliza a autenticação e a emissão de tokens para várias aplicações e APIs.

Qual a diferença entre OpenID Connect e OAuth 2.0?

O OAuth 2.0 trata do acesso a APIs por meio de tokens. Já o OpenID Connect adiciona uma camada de autenticação sobre ele.

O Identity Server substitui o ASP.NET Identity?

Não. O ASP.NET Identity gerencia usuários, senhas e perfis, enquanto o servidor de identidade emite tokens e pode usar o ASP.NET Identity como base de usuários.

O IdentityServer4 ainda é mantido?

Não. O suporte terminou em 2022, e a evolução do projeto seguiu como Duende IdentityServer.

APIs em outras linguagens podem usar o Identity Server?

Sim. Como ele segue padrões abertos, qualquer linguagem com biblioteca de OpenID Connect ou validação de JWT consegue se integrar.