Minhas Cicatrizes com o Identity Server 4 (IDS4)

Wilson Santos
9 min readJan 29, 2019

Historinha:

IDS4 é uma ferramenta fantástica para centralizar processos de Autenticação pode ser usado por uma ou várias aplicações , o modelo SingleSignOn , onde você tem apenas uma aplicação cuidando desse processo.

Com ele temos uma implementação de OAuth2 testada e certificada, uma implementação MVC para fazer as principais tarefas de SSO , e uma ótima documentação, alem do melhor, faz parte do .net foundations do.net core, isso nos deixa mais confortáveis em adota-lo.

Mas Como nem tudo são flores ele é temperamental , e se não estiver tudo do jeitinho dele, as coisas não funcionam;

Vou narrar aqui algumas situações que me deram dor de cabeça;

Entenda o fluxo dessa joça

Tem um monte de fluxo bonito na internet , na documentação do IDS4 também tem, mas é mais ou menos assim , o front faz um redirect para o SSO com uma url de retorno e o clientID, o SSO pergunta seu login e Senha e valida as informações da URL com os clients configurados nele.

Manda de volta para a aplicação com um token, chamado access token , você pega esse token guarda e manda no header de cada requisição para a API, a api define que o processo de autenticação sera delegado para um servidor de autenticação em seu pipeLine de inicialização , isso integra com o mecanismo de Autenticação e Autorização do próprio asp net, e é mais ou menos assim que funciona.

Conheça alguns Endpoints

O IDS 4 é uma excelente implementação , mas é sempre bom conhecer o minimo sobre o protocolo Oauth2, saber quais são os endpoints são um bom começo, para isso temos esse endereço que fornece toda a configuração do seu IDS4.

http://localhost:4000/.well-known/openid-configuration

por exemplo para implementar uma aplicação SPA sem usar plugin nenhum basta saber que a url para você autenticar no SSO é :

http://localhost:4000/connect/authorize,

essa controller não existe no exemplo do IDS4 é interno, olha como eu montei meu login, isso esta disponível em um serviço angular no meu git o AuthServices

Flows

O protocolo Oauth 2 oferece vários fluxos de Autenticação, um para cada cenário

Costumo utilizar o Fluxo Implicit Flow para aplicações web SPA que precisam se autenticar em um SSO

Costumo usar o ResourceOwnerPassword para aplicações que podemos armazenar um Client e um Secret com segurança como uma aplicação Server Side, ou um aplicativo nativo que será empacotado para dispositivos moveis , para fazer uma customização do login no servidor pode implementar a interface IResourceOwnerPasswordValidator, escrever o método public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) e fazer sua customização veja em ResourceOwnerPasswordValidator

E também uso o ClientCredentials para autenticar aplicações com outras aplicações , tipo uma api falando com outra, coisas desse tipo.

aqui no AuthorityEndPoint usamos a url do SSO + “/connect/token” Ex: http://localhost:4000/connect/token

Configurações conflitantes do Front com o Client configurado no SSO

No meu contexto costumo criar para um sistema três aplicações, uma para o Front outra para Api e outra para o SSO, isso é muito bom em termos de escalabilidade, deploy e devops , mas gera uma complicação nas configurações pois existe uma amarração do front que aposta para o SSO , o SSO que conhece qual é a url da aplicação e a API que conhece qual é a url do Servidor de SSO.

perceba que existe uma variável na url chamada returnUrl , ela é passada pelo front para o SSO e assim o SSO verifica através do ClientID se o Client configurado no SSO tem essa mesma url , caso as duas não batam , o erro retornado é Cliente não Autorizado!

observe abaixo uma configuração de um client , onde informações sobre as urls envolvidas no processo são especificadas em um fluxo Implicit

veja o fluxo de novo;

vejam o danado do Erro.

Consentimento

o Auth2, foi projetado para integrar várias aplicações em um único sistema de Autenticação , dessa forma diferentes aplicações poderiam usar o mesmo mecanismo para Autenticar seus usuários , mas para isso precisam disponibilizar algumas informações do usuário , e para isso é preciso o consentimento do usuário. Essas informações são geralmente fornecidas em um modelo chamado Claims , onde constam informações como nome , sobrenome , e-mail etc, mas caso não seja esse seu cenário , configurar um Client para evitar não solicitar um consentimento é muito simples, basta configurar o parâmetro RequireConsent

TTL

Tempo de vida do Token, o padrão para o Token deixar de ser valido é de uma hora , mas podemos aumentar ou diminuir , a recomendação é de 30 minutos, depois pede para o usuário se re-logar no sistema.

Claims

São informações do usuário que podemos trafegar dentro do token , mantendo uma especie de sessão que trafega pelo request entre o Front e a API, o SSO já coloca algumas claims no token como o Id do usuário , uma claim chamada SubjectId, mas podemos colocar nossas próprias informações , desde de que façamos essa configuração aqui;

Certificado

o SSO usa certificados para gerar os tokens , o mecanismo é conhecido como mecanismo de assinatura de forma que apenas token gerado sob a chave privada daquele certificado são validos para aquela instancia do SSO, para isso configuramos esse método

esse certificado é um certificado Auto Assinado , da pra fazer pelo IIS mesmo.

Tipos de Tokens

Olha tem vários tipos de Token , mas eu não sei quais são todos , o que nos usamos é um token chamando bearer vejam ;

vocês podem ler o token através desse site , http://jwt.io/

Apenas ler , mas não modificar , essa é a grande segurança da coisa, os tokens são invioláveis, por conta da Assinatura digital , qualquer mudança vão tornar o token invalido.

Tamanho dos Tokens

Não abuse , tokens muito grandes vão quebrar sua aplicação, já aconteceu comigo, não sei o tamanho exato mas os mantenha pequenos.

Domínios, Dns e Subdomínios

não se esqueça que você tem três domínios diferentes, e que é importante que existam limitações relacionados as configurações de CORs, essa configuração vão evitar ataques de outras aplicações.

Uma outra coisa que apanhei muito foi quando coloquei alguns sub domínios para o SSO isso me fez cair no cenário citado acima de urls conflitantes , depois de alguma pesquisa achei essa configuração que define quem vai ser o domínio emissor do seu token, e ai seu SSO pode ter várias URLs, de vários domínios diferentes , isso se torna útil em uma aplicação multi-tenant.

CSP (Content Security Policy)

Essa sigla , define um conjunto de configurações de segurança que impedem que algumas peripécias sejam feitas no HTML no JavaScript e CSS, carregamento de scripts externos imagens etc.

Aqui temos algumas configurações que permitem algumas coisinhas, definir um style in line, scripts externos , imagens etc.

LogOut

Para deslogar você joga o token fora , e chama o logOut que vem implementado no SSO do IDS4 , mas atenção o token ainda esta valido no servidor e portanto precisa ser revogado pelo url /connect/revocation, confesso que ainda não implementei isso então segue a documentação do processo de revogação

Persistência

Eu tenho usando o SSO com os clients , resources em memoria , isso não é aconselhável mas , honestamente não tenho tido muitos problemas, normalmente essas configurações são estáticas mesmo, tenho meia duzia de clients , alguns escopos e pronto , nunca mais mexo nisso, a unica coisa que não da pra usar, é o método de exemplo AddTemporarySigningCredential, esse ai da problema pois o expira ai o token deixa de estar valido, fica ruim, o resto não tenho muito do que reclamar não. Uso assim ;

mas podemos definir que usaremos um banco para persistir toda a configuração do IDS4, vejam abaixo;

Configura o Servidor
Implementa o método para inicializar o banco

e no método configure da classe StartUp chama o método

Alem disso , é preciso rodar as “migrations” use o console na pasta da aplicação e rode os seguintes comandos;

Para criar, vá até a pasta do SSO;

dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDbdotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb

Caso queira remover;

dotnet ef migrations remove -c PersistedGrantDbContext
dotnet ef migrations remove -c ConfigurationDbContext

e para rodar efetivamente no banco;

dotnet ef database update -c PersistedGrantDbContext
dotnet ef database update -c ConfigurationDbContext

tenho um exemplo de SSO com banco de dados SQL server no git

Também existem iniciativas prontas com uma GUI pronta para administrar um SSO , podendo fazer todas as suas configurações de forma User Friendly , dia desses um amigo me mandou esse exemplo aqui :

Também existem iniciativas prontas com uma GUI pronta para administrar um SSO , podendo fazer todas as suas configurações de forma User Friendly , dia desses um amigo me mandou esse exemplo aqui :

Também tem esse;

ainda não usei , mas parece ser muito bom.

Cuidado com classe TesteUser

Como eu disse anteriormente , podemos manter as configurações do IDS4 em memoria , e para testar podemos configurar a inicialização dele com o método .AddTestUsers(Config.GetUsers()) , uma extensão do middleare services.AddIdentityServer()

na ultima versão do IDS4, eu presenciei um amigo que pegou a implementação Default do IDS4 e apenas implementou um repositório para poder acessas os usuários da sua aplicação, mas esqueceu de tirar esse método do Startup , isso fazia o sistema não logar de forma alguma, até que encontramos uma alma caridoso que relatou o fato no Stackoverflow

Logs

É imprescindível que você habilite logs no SSO , pois vão acontecer muito problemas e as vezes apenas os logs podem nos salvar;

Estou usando o serilog , é uma boa opção, da uma olhada no SSO do meu git que você encontra mais detalhes do processo de implementação de Logs, inclusive tenho um artigo sobre logs também (Logs no .net core com configurações no appsettings.json)

Algumas implementações eu abstrai e encapsulei para reuso (vocês podem encontra-las no meu github)

  1. AuthServices
  2. Startup
  3. ResourceOwnerPasswordValidator
  4. Config

se quiser saber mais sobre IDS4;

  1. SSO Customizando o fluxos Resource Owner Password e Client Credentials
  2. Swagger integrado com SSO Identity Server 4 .net core 2.0
  3. Integração HangFire com SSO Identity Server 4 .net core 2.0
  4. https://identityserver4.readthedocs.io/en/latest/

--

--

Wilson Santos
Wilson Santos

Written by Wilson Santos

Nos últimos 15 anos, venho desenvolvendo , aperfeiçoando e integrando sistemas, sou apaixonado por desenvolver e ensinar, nem tanto por escrever!.

Responses (1)