Este projeto é um Host do .Net Aspire.
Ele provisiona e orquestra toda infra estrutura localmente.
Para rodar é necessário estar com o docker rodando.
O Host do Aspire provisionará uma imagem do SQL Server via Docker na inicialização do Host.
Para acessar o banco atravez do SQL Server Management Studio você deve conectar com usuário sa
a senha está fixada S3nh@F0rte123! e porta 5433.
Nessa caso o endereço fica tcp:127.0.0.1,5433.
É possivel mudar para porta senha dinâmica. Caso queira a senha vc pode obter atravez do painel do Aspire
na env MSSQL_SA_PASSWORD ou via linha de comando dotnet user-secrets list na saída Parameters:sqlserver-password.
O endereço do banco será levantado em tcp:127.0.0.1,porta e a porta é criada dinamicamente.
A porta vc pode pegar no painel do Aspire ou via comando docker ps --filter name=sql
na saída da coluna PORTS da tabela exemplo:
| CONTAINER ID | IMAGE | COMMAND | CREATED | STATUS | PORTS | NAMES |
|---|---|---|---|---|---|---|
| aa02d5bc8dcf | mcr.microsoft.com/mssql/server:2022-latest | "/opt/mssql/bin/perm…" | 51 minutes ago | Up 51 minutes | 127.0.0.1:53028->1433/tcp | sqlserver-ygcdhgvf |
Nessa caso o endereço fica tcp:127.0.0.1,53028.
A manutenção das migrações de cada módulo é facilitada por scripts específicos:
- Para o módulo de Frota: utilize o script
AddMigrationFleetModule.ps1. - Para o módulo de Checklists: utilize o script
AddMigrationChecklistsModule.ps1.
Esses scripts automatizam o processo de criação de novas migrações para cada contexto (DbContext) e garantem padronização na nomenclatura (timestamp) e uso do projeto de inicialização correto.
Cada módulo possui um job de migração dedicado (Worker Service) responsável por aplicar as migrações ao iniciar:
VCheck.Modules.Fleet.MigrationService.csprojVCheck.Modules.Checklists.MigrationService.csproj
A orquestração local desses jobs é realizada pelo Host Aspire (VCheck.Host.csproj). Ao iniciar o Host (dotnet run no projeto Host),
ele provisiona os recursos necessários (SQL Server, Keycloak, etc.) e executa automaticamente os jobs de migração para garantir que o banco de
dados esteja atualizado conforme os modelos de cada módulo antes de subir a API principal.
Fluxo simplificado de inicialização:
- Aspire inicia e provisiona o container do SQL Server.
- Jobs de migração dos módulos são executados e aplicam pendências (se existirem).
- A API principal somente inicia após a conclusão dos jobs de migração (cadeia de dependências configurada no Host).
A solução de identidade segue o System Design (uso de IdP externo) e os requisitos de negócio de controlar perfis Executor e Supervisor.
No Program.cs do Host:
var keycloak = builder.AddKeycloak("keycloak", adminUsername: username, adminPassword: password)
.WithDataVolume()
.WithRealmImport("./KeycloackConfiguration/transport-realm.json");Isso executa um container Keycloak, persiste dados (volume) e importa automaticamente o realm transport a partir do arquivo JSON.
A API (vcheck-api) declara dependência com .WithReference(keycloak).WaitFor(keycloak) garantindo que Keycloak esteja pronto antes de subir a API.
Arquivo: src/Host/KeycloackConfiguration/transport-realm.json.
Contém:
- Roles de realm:
executor(executa e preenche checklists)supervisor(aprova ou reprova checklists)
- Usuários iniciais (senha
123):user.executor-> roleexecutoruser.supervisor-> rolesupervisoruser.comum-> role padrão (default-roles-transport) sem permissões específicas de checklist
- Client confidencial
vcheck-api(publicClient=false) com:secret:S3cr3tdirectAccessGrantsEnabled: true (habilita Resource Owner Password / password flow)- Mappers:
- Audience para incluir
vcheck-apino access token - Realm roles em claim
roles(multivalued)
- Audience para incluir
Esses elementos suportam:
- RF-01..RF-06 (executor inicia/preenche; supervisor aprova) através de segregação por roles
- RNF Concorrência / Auditabilidade ao permitir tokens JWT com claims de usuário e roles
Em src/API/Program.cs:
builder.Services.AddAuthentication()
.AddKeycloakJwtBearer(serviceName: "keycloak", realm: "transport", options =>
{
options.Audience = "vcheck-api";
options.Authority = "http://localhost:8080/realms/transport"; // ajustado dinamicamente via configuração Aspire
options.TokenValidationParameters.RoleClaimType = "roles"; // claim usada para [Authorize(Roles="...")]
if (builder.Environment.IsDevelopment()) options.RequireHttpsMetadata = false;
});O Swagger foi configurado com fluxo OAuth2 Password apontando para os endpoints do realm.
Passos:
- Suba o Host:
dotnet runemVCheck.Host(Aspire inicia Keycloak e API). - Abra o Swagger da API (ex.: https://localhost:/swagger).
- Clique em "Authorize".
- Preencha:
- client_id:
vcheck-api - client_secret:
S3cr3t - username:
user.executor(ouuser.supervisor) - password:
123 - scopes: selecione
openid profile emailse desejar.
- client_id:
- Após autorizar, o botão mostrará o lock fechado e as requisições incluirão o Bearer token.
Use user.executor para fluxos de execução de checklist e user.supervisor para endpoints futuros de aprovação.
curl -X POST \
http://localhost:8080/realms/transport/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=vcheck-api" \
-d "client_secret=S3cr3t" \
-d "username=user.executor" \
-d "password=123"Resposta conterá access_token (JWT) usado no header: Authorization: Bearer <token>.
- Podem ser adicionadas novas roles (ex.: auditor) estendendo o mesmo processo de realm import.
- Para produção recomenda-se TLS, rotação do client secret e desabilitar password flow substituindo por Authorization Code + PKCE conforme estratégia de frontend.
Isso alinha a implementação ao System Design (IdP externo, segurança gerenciada) e aos requisitos de negócio de perfis distintos Executor/Supervisor.