ASP.NET Core 3.1 - IdentityServer4 - EF-support (Parte 4)

Na Parte 1 falei sobre a configuração do IdentityServer4 para que funcione em memória, esta forma possui alguns benefícios de curto prazo para testar e validar o processo de desenvolvimento dos serviços e para que você não dependa de um banco de dados.

Como já comentei próprio IdentityServer sugere que você não use a configuração in-memory em produção e sim passe a utilizar a configuração em store como é chamado, ou seja, utilizando um banco de dados onde os dados possam ser persistidos. Então, vamos utilizar o SQLServer para ser a nossa store.

No meu caso eu estou utilizando docker para poder ter um banco de dados disponível de forma rápida e prática em ambiente de desenvolvimento. Os DBA's reforçam que você nunca deve ter um banco de dados SQLServer em produção dentro de um container, porém para desenvolvimento é uma prática natural e muito ágil pela facilidade e velocidade de configuração.

Docker

Não entrarei muito em detalhes sobre o docker, mas se você quiser usá-lo você tem duas opções:

  • Se você tiver Windows Home instalado, vai precisar usar o docker como se fosse serviços virtualizados pelo VirtualBox por exemplo;

  • Para Windows Pro, você pode baixar o docker desktop vai facilitar muito a sua vida e é o meu caso.

Eu estou utilizando o docker com containers em Linux, pois as imagens são menores.

Instalando SQLServer com Docker

Basta você abrir o PowerShell como administrador e digitar o comando a seguir:

docker run -e 'ACCEPTEULA=Y' -e 'SAPASSWORD=Password!' -p 1433:1433 -d --restart unless-stopped -v sqlserver-volume:/var/opt/mssql mcr.microsoft.com/mssql/server:2017-latest

O comando acima realiza o download da última versão do SQLServer Docker e cria o volume 'sqlserver-volume' automaticamente caso não exista.
O comando --restart unless-stopped é para caso o servidor reinicie (ou seu PC), ao retornar inicializa o container automaticamente. Mais detalhes aqui
O uso do volume permite a persistência dos dados caso o container do SQLServer seja eventualmente removido ou recriado em outra versão. Caso você remover o container e criá-lo novamente, o volume vai apoiar na manutenção da base de dados que já existia, sem perder as informações.

  • Usuário: sa

  • Senha: Password!

  • Porta: 1433, esta já é a porta padrão do SQLServer

Através do Visual Studio, você tem o SQL Server Object Explorer, adicione um novo servidor com as configurações conforme a tela abaixo e pronto, você se conectará ao banco de dados que foi criado.

SQLServer Docker

Funcionalidades

As funcionalidades disponíveis no IdentityServer estão divididas em duas áreas: configuration store e operational store. Ambas podem ser usadas de forma independente ou juntas dependendo das necessidades.

Estas funcionalidades são utilizadas para que os dados possam ser persistidos e utilizados a partir do suporte do EntityFramework em uma base de dados.

Configuration Store

Esta configuração está relacionada ao armazenamento das informações que representam: client, identity resource, API resource, ou CORS e a classe de contexto é a ConfigurationDbContext.

Operational Store

Esta configuração está relacionada ao armazenamento das informações que representam: authorization grants, consents e tokens (refresh e reference) e a classe de contexto é a PersistedGrantDbContext.

Statup

A configuração do arquivo startup.cs fica conforme a seguir.

appsettings

Agora que não estamos mais trabalhando com o IdentityServer em memória, podemos limpar o arquivo de configurações e colocarmos a string de conexão com o SQLServer conforme a seguir.

Seed

Nada adianta termos um banco de dados que não possui dados, então criei alguns métodos de extensão (extension methods) que são chamados lá no Startup.cs no método Configuration. Estes métodos vão criar o banco de dados e já adicionar os dados que estavam antes no arquivo de configurações. O ideal seria termos uma tela para cadastrar os dados, mas para acelerarmos este processo e termos um resultado mais palpável esta forma é mais simples neste momento.

Grant Type - Client Credentials

Vamos falar um pouco sobre o grant type utilizado pelo client que a API de Pagamento usa para permitir o acesso do token do escopo payment.
Este grant type é o mais simples e mais utilizado na Machine to Machine Communication. O token é gerado em nome de um client sem que haja relação com um usuário da aplicação, usuário aqui significa um ser humano que acessa uma tela de login e informa seu usuário e senha para se logar.
Quando o token é garado, as únicas informações necessárias são o ID e a senha (secret) e com o token pertencendo ao escopo payment é possível realizar o acesso à API de Pagamento.

Migrations

Para iniciar o banco de dados, precisamos das famosas migrations, para isso basta executar os comandos a seguir dentro do visual studio através do Package Manager Console, para isso você vai precisar que os pacotes abaixo estejam instalados:

Microsoft.EntityFramework Microsoft.EntityFramework.Tools

Add-Migration Initial -Context ConfigurationDbContext Update-Database -Context ConfigurationDbContext

Add-Migration Initial -Context PersistedGrantDbContext Update-Database -Context PersistedGrantDbContext

Execução

Depois de ter feito tudo isso, rode o projeto do IdentityServer, pode levar alguns segundos até ele criar a base de dados para aí sim salvar as informações e você pode voltar lá na Parte 3, buscar o token que permite acessar a API payment que foi configurado e chamar a API de Pagamento através do Postman conforme as imagens de exemplo.

Caso você tenha dúvidas, eu disponibilizei o código no GitHub em um branch chamado identityserver-sqlserver.

Continua em ASP.NET Core 3.1 - IdentityServer4 - EF-Identity (Parte 5).