![]() |
VOOZH | about |
dotnet add package Skoruba.Duende.IdentityServer.Admin.EntityFramework.Admin --version 3.0.0-rc4
NuGet\Install-Package Skoruba.Duende.IdentityServer.Admin.EntityFramework.Admin -Version 3.0.0-rc4
<PackageReference Include="Skoruba.Duende.IdentityServer.Admin.EntityFramework.Admin" Version="3.0.0-rc4" />
<PackageVersion Include="Skoruba.Duende.IdentityServer.Admin.EntityFramework.Admin" Version="3.0.0-rc4" />Directory.Packages.props
<PackageReference Include="Skoruba.Duende.IdentityServer.Admin.EntityFramework.Admin" />Project file
paket add Skoruba.Duende.IdentityServer.Admin.EntityFramework.Admin --version 3.0.0-rc4
#r "nuget: Skoruba.Duende.IdentityServer.Admin.EntityFramework.Admin, 3.0.0-rc4"
#:package Skoruba.Duende.IdentityServer.Admin.EntityFramework.Admin@3.0.0-rc4
#addin nuget:?package=Skoruba.Duende.IdentityServer.Admin.EntityFramework.Admin&version=3.0.0-rc4&prereleaseInstall as a Cake Addin
#tool nuget:?package=Skoruba.Duende.IdentityServer.Admin.EntityFramework.Admin&version=3.0.0-rc4&prereleaseInstall as a Cake Tool
Modern admin UI for Duende IdentityServer and ASP.NET Core Identity.
π .NET
π React
π License
π Discord
π Next generation Admin UI: v3.0.0-rc4
π¦ Previous stable version: v2.7.0
release/2.7.0 branch.The UI is built with Tailwind CSS and shadcn/ui components.
Define and track configuration rules for clients, API resources, and identity resources:
Note: Using older .NET versions may cause 502.5 errors on IIS or application startup failures.
π Database note:
This template includes default EF migrations. Review them and back up your database before applying.
βΉοΈ Migration note from IdentityServer4.Admin:
TheUserSecretsIdfor Admin, Admin API, and STS projects remains the same as in the olderSkoruba.IdentityServer4.Adminsolution to ease config migration. If you still have secrets from the old project on your machine, they will be reused (e.g.,ApplySeedcould point at your old DB). Change or clear user secrets if you need isolation.
dotnet new install Skoruba.Duende.IdentityServer.Admin.Templates::3.0.0-rc4
dotnet new skoruba.duende.isadmin \
--name MyProject \
--title MyProject \
--adminemail "admin@example.com" \
--adminpassword "Passw0rd-123" \
--adminrole MyRole \
--adminclientid MyClientId \
--adminclientsecret MyClientSecret \
--dockersupport true \
--requirepushedauthorization true
| Option | Description |
|---|---|
--name |
Project name |
--title |
Admin UI title and footer text |
--adminemail |
Initial admin email |
--adminpassword |
Initial admin password |
--adminrole |
Role name used for admin authorization |
--adminclientid |
Client ID for the Admin UI OIDC client |
--adminclientsecret |
Client secret for the Admin UI OIDC client |
--dockersupport |
Include Docker support (true / false) |
--requirepushedauthorization |
Require PAR for admin client (true / false, default true). Note: PAR requires Duende IdentityServer Business Edition or higher. More info |
Note: This section is for developers who want to clone and contribute to the repository. If you want to use the template, see the section above.
The solution contains three runnable services:
| Service | Project | Purpose |
|---|---|---|
| STS | Skoruba.Duende.IdentityServer.STS.Identity |
IdentityServer + authentication |
| Admin API | Skoruba.Duende.IdentityServer.Admin.Api |
REST API backend |
| Admin UI | Skoruba.Duende.IdentityServer.Admin |
SPA host |
git clone https://github.com/skoruba/Duende.IdentityServer.Admin
cd Duende.IdentityServer.Admin
cd src/Skoruba.Duende.IdentityServer.Admin.UI.Client
npm install
cd ../..
Open three terminals and run:
# Terminal 1: STS (IdentityServer)
cd src/Skoruba.Duende.IdentityServer.STS.Identity
dotnet run
# Terminal 2: Admin API
cd src/Skoruba.Duende.IdentityServer.Admin.Api
dotnet run
# Terminal 3: Admin UI Host
cd src/Skoruba.Duende.IdentityServer.Admin
dotnet run
| Service | URL |
|---|---|
| STS | https://localhost:44310 |
| Admin API | https://localhost:44302 |
| Admin UI | Check console output (usually https://localhost:7127) |
By default, database migrations and seed data are enabled in Admin API (
ApplyDatabaseMigrations,ApplySeed).
Tip: For the fastest onboarding, use the
dotnet runapproach above. Docker requires custom domain and certificates.
Update your hosts file to resolve skoruba.local:
Windows: C:\Windows\System32\drivers\etc\hosts
Linux / macOS: /etc/hosts
127.0.0.1 skoruba.local sts.skoruba.local admin.skoruba.local admin-api.skoruba.local
Use mkcert to generate self-signed local certificates.
cd shared/nginx/certs
mkcert --install
copy $env:LOCALAPPDATA\mkcert\rootCA-key.pem ./cacerts.pem
copy $env:LOCALAPPDATA\mkcert\rootCA.pem ./cacerts.crt
# Generate skoruba.local certificates
mkcert -cert-file skoruba.local.crt -key-file skoruba.local.key skoruba.local *.skoruba.local
mkcert -pkcs12 skoruba.local.pfx skoruba.local *.skoruba.local
cd shared/nginx/certs
mkcert -install
# Copy root certificates (adjust paths for your system)
# macOS: ~/Library/Application\ Support/mkcert/
# Linux: ~/.local/share/mkcert/
cp "$(mkcert -CAROOT)/rootCA-key.pem" ./cacerts.pem
cp "$(mkcert -CAROOT)/rootCA.pem" ./cacerts.crt
# Generate skoruba.local certificates
mkcert -cert-file skoruba.local.crt -key-file skoruba.local.key skoruba.local *.skoruba.local
mkcert -pkcs12 skoruba.local.pfx skoruba.local *.skoruba.local
docker-compose build
docker-compose up -d
Docker setup is based on bravecobra's repository β thanks! π
Docker images are available on Docker Hub.
To publish images, check build/publish-docker-images.ps1 and update the profile name.
The solution uses the following DbContext classes:
AdminIdentityDbContext β ASP.NET Core Identity dataAdminLogDbContext β Logging dataIdentityServerConfigurationDbContext β IdentityServer configuration storeIdentityServerPersistedGrantDbContext β IdentityServer operational storeAuditLoggingDbContext β Audit loggingIdentityServerDataProtectionDbContext β Data protection keysAdminConfigurationDbContext β Admin configuration and monitoring (added in v3.0.0)Switch providers in appsettings.json:
"DatabaseProviderConfiguration": {
"ProviderType": "SqlServer"
}
SQL Server (LocalDB):
Data Source=(LocalDb)\\MSSQLLocalDB;database=DuendeIdentityServerAdmin;trusted_connection=yes;
PostgreSQL:
Server=localhost;Port=5432;Database=DuendeIdentityServerAdmin;User Id=sa;Password=#;
Note: Initial migrations are included in the repository.
Use the PowerShell script in build/add-migrations.ps1:
.\add-migrations.ps1 -migration DbInit -migrationProviderName SqlServer
Arguments:
--migration β Migration name--migrationProviderName β Provider type (choices: All, SqlServer, PostgreSQL)Seed data is configured in:
identityserverdata.json β IdentityServer clients and resourcesidentitydata.json β ASP.NET Core Identity users and rolesEnable seeding via:
Option 1: Command line
dotnet run /seed
Option 2: Configuration (appsettings.json)
"SeedConfiguration": {
"ApplySeed": true
},
"DatabaseMigrationsConfiguration": {
"ApplyDatabaseMigrations": true
}
AuthorizationConsts.AdministrationPolicyAdministrationRole (appsettings.json)Configuration in appsettings.json:
"AdministrationRole": "SkorubaIdentityAdminAdministrator"
Azure Key Vault supports:
"AzureKeyVaultConfiguration": {
"AzureKeyVaultEndpoint": "https://your-vault.vault.azure.net/",
"ReadConfigurationFromKeyVault": true,
"ClientId": "",
"ClientSecret": "",
"UseClientCredentials": true
}
For Azure App Service: Only specify AzureKeyVaultEndpoint.
Outside Azure: Use client credentials (register app in Azure Portal).
"DataProtectionConfiguration": {
"ProtectKeysWithAzureKeyVault": true
},
"AzureKeyVaultConfiguration": {
"DataProtectionKeyIdentifier": "https://your-vault.vault.azure.net/keys/dataprotection"
}
"AzureKeyVaultConfiguration": {
"IdentityServerCertificateName": "IdentityServerSigningCert"
}
Uses Serilog with the following sinks (configured in serilog.json):
Example configuration:
{
"Serilog": {
"MinimumLevel": {
"Default": "Error",
"Override": {
"Skoruba": "Information"
}
},
"WriteTo": [
{
"Name": "Console"
},
{
"Name": "File",
"Args": {
"path": "log.txt",
"rollingInterval": "Day"
}
},
{
"Name": "MSSqlServer",
"Args": {
"connectionString": "...",
"tableName": "Log"
}
}
]
}
}
Integrated via skoruba/AuditLogging.
Configuration in appsettings.json:
"AuditLoggingConfiguration": {
"Source": "IdentityServer.Admin.Web",
"SubjectIdentifierClaim": "sub",
"SubjectNameClaim": "name",
"IncludeFormVariables": false
}
Audit logs are stored in the AuditLog table.
Usage example:
await AuditEventLogger.LogEventAsync(new ClientDeletedEvent(client));
Configure external providers in STS (appsettings.json):
"ExternalProvidersConfiguration": {
"UseGitHubProvider": false,
"GitHubClientId": "",
"GitHubClientSecret": "",
"UseAzureAdProvider": false,
"AzureAdClientId": "",
"AzureAdTenantId": "",
"AzureInstance": "https://login.microsoftonline.com/",
"AzureAdSecret": "",
"AzureAdCallbackPath": "/signin-oidc",
"AzureDomain": ""
}
Supported providers:
Azure AD setup guide:
Quickstart: Sign in users in ASP.NET Core web apps
"SendgridConfiguration": {
"ApiKey": "",
"SourceEmail": "",
"SourceName": ""
}
"SmtpConfiguration": {
"From": "",
"Host": "",
"Login": "",
"Password": ""
}
All services expose a /health endpoint for monitoring:
https://localhost:7127/healthhttps://localhost:44302/healthhttps://localhost:44310/healthChecks include:
Translations are stored in /i18n.
Currently supported:
Contributing translations:
Feel free to submit a PR with your translation! π
Swagger UI is available at:
https://localhost:44302/swagger
Configuration (appsettings.json):
"AdminApiConfiguration": {
"IdentityServerBaseUrl": "https://localhost:44310",
"OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui",
"OidcApiName": "skoruba_identity_admin_api"
}
Choose between Username or Email login:
"LoginConfiguration": {
"ResolutionPolicy": "Username"
}
Enable or disable user registration:
"RegisterConfiguration": {
"Enabled": true
}
Identity DTO/entity mapping in Skoruba.Duende.IdentityServer.Admin.BusinessLogic.Identity is handled by IdentityDataMapper.
By default:
PasswordHash, SecurityStamp, ConcurrencyStamp, NormalizedUserName, NormalizedEmail) are protected during DTO β entity updates.If your custom UserDto / RoleDto and IdentityUser / IdentityRole share the same custom property name, no extra configuration is needed.
When names differ, implement customizers and register them in DI:
services
.AddAdminAspNetIdentityServices<...>()
.AddIdentityUserMappingCustomizer<ApplicationUserDto, ApplicationUser, ApplicationUserMappingCustomizer>()
.AddIdentityRoleMappingCustomizer<ApplicationRoleDto, ApplicationRole, ApplicationRoleMappingCustomizer>();
Customizers implement:
IIdentityUserMappingCustomizer<TUserDto, TUser>IIdentityRoleMappingCustomizer<TRoleDto, TRole>If you need full control, replace the default IIdentityDataMapper<...> registration in DI with your own implementation after calling AddAdminAspNetIdentityServices.
The solution contains unit and integration tests for all major components.
Skoruba.Duende.IdentityServer.STS.Identity β IdentityServer with ASP.NET Core Identity
Skoruba.Duende.IdentityServer.Admin.Api β REST API with Swagger
Skoruba.Duende.IdentityServer.Admin β .NET hostSkoruba.Duende.IdentityServer.Admin.UI β UI servicesSkoruba.Duende.IdentityServer.Admin.UI.Spa β Precompiled React assetsSkoruba.Duende.IdentityServer.Admin.UI.Client β React source codeSkoruba.Duende.IdentityServer.Admin.BusinessLogic β IdentityServer DTOs, services, repositoriesSkoruba.Duende.IdentityServer.Admin.BusinessLogic.Identity β Identity DTOs, services, repositoriesSkoruba.Duende.IdentityServer.Admin.BusinessLogic.Shared β Shared logicSkoruba.Duende.IdentityServer.Admin.EntityFramework β Core EF entitiesSkoruba.Duende.IdentityServer.Admin.EntityFramework.Configuration β Entity configurationsSkoruba.Duende.IdentityServer.Admin.EntityFramework.Extensions β EF extensionsSkoruba.Duende.IdentityServer.Admin.EntityFramework.Identity β Identity repositoriesSkoruba.Duende.IdentityServer.Admin.EntityFramework.Shared β DbContextsSkoruba.Duende.IdentityServer.Admin.EntityFramework.SqlServer β SQL Server migrationsSkoruba.Duende.IdentityServer.Admin.EntityFramework.PostgreSQL β PostgreSQL migrationsSkoruba.Duende.IdentityServer.Shared β Shared DTOsSkoruba.Duende.IdentityServer.Shared.Configuration β Shared configurationSkoruba.Duende.IdentityServer.Admin.UnitTests β Unit testsSkoruba.Duende.IdentityServer.Admin.Api.IntegrationTests β API integration testsSkoruba.Duende.IdentityServer.STS.IntegrationTests β STS integration testsSkoruba.Duende.IdentityServer.Admin.UI.Client.IntegrationTests β Playwright UI integration tests (OIDC login flow + Admin UI assertions)The UI E2E test project is located in:
tests/Skoruba.Duende.IdentityServer.Admin.UI.Client.IntegrationTestsTo run it:
cd tests/Skoruba.Duende.IdentityServer.Admin.UI.Client.IntegrationTests
npm install
npx playwright install chromium
npm test
Default expected runtime services:
https://localhost:44310https://localhost:44302https://localhost:7127E2E_ADMIN_URL for Playwright: https://localhost:50445Important: The seeded OIDC client redirect URIs and CORS origins in
src/Skoruba.Duende.IdentityServer.Admin.Api/identityserverdata.jsonusehttps://localhost:50445by default. If you run the Admin UI onhttps://localhost:7127instead, update the client configuration (or the PlaywrightE2E_ADMIN_URL) so redirects and CORS validation continue to work.
The tests load credentials and expected client data from seed files:
src/Skoruba.Duende.IdentityServer.Admin.Api/identitydata.jsonsrc/Skoruba.Duende.IdentityServer.Admin.Api/identityserverdata.jsonFor detailed release history and upcoming features, see .
Upcoming releases:
This repository is licensed under .
Duende IdentityServer is available under both a FOSS (RPL) and commercial license.
For production environments, you need a specific license. More info:
https://duendesoftware.com/products/identityserver#pricing
This repository uses source code from:
https://github.com/DuendeSoftware/IdentityServer.Quickstart.UI
Licensed under: https://github.com/DuendeSoftware/IdentityServer.Quickstart.UI/blob/main/LICENSE
Thanks to:
Author: Jan Ε koruba
Email: jan@skoruba.com
Feedback is welcome! Feel free to create an issue or send me an email. Thank you! βΊοΈ
If you like this project, you can support me:
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
Showing the top 1 NuGet packages that depend on Skoruba.Duende.IdentityServer.Admin.EntityFramework.Admin:
| Package | Downloads |
|---|---|
|
Skoruba.Duende.IdentityServer.Admin.BusinessLogic
Business Logic layer for the administration of the Duende IdentityServer |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.0-rc4 | 281 | 5/18/2026 |
| 3.0.0-rc3 | 80 | 5/15/2026 |
| 3.0.0-rc2 | 120 | 5/8/2026 |
| 3.0.0-rc1 | 92 | 5/8/2026 |
| 3.0.0-preview.24 | 133 | 4/24/2026 |
| 3.0.0-preview.23 | 62 | 4/24/2026 |
| 3.0.0-preview.22 | 402 | 2/3/2026 |
| 3.0.0-preview.21 | 96 | 2/1/2026 |
| 3.0.0-preview.20 | 73 | 1/31/2026 |
| 3.0.0-preview.19 | 76 | 1/30/2026 |
| 3.0.0-preview.18 | 77 | 1/30/2026 |
| 3.0.0-preview.17 | 71 | 1/30/2026 |
| 3.0.0-preview.16 | 75 | 1/21/2026 |
| 3.0.0-preview.15 | 73 | 1/21/2026 |
| 3.0.0-preview.14 | 80 | 1/17/2026 |
| 3.0.0-preview.13 | 80 | 1/14/2026 |
| 3.0.0-preview.12 | 76 | 1/14/2026 |
| 3.0.0-preview.11 | 90 | 1/14/2026 |
| 3.0.0-preview.10 | 82 | 1/14/2026 |
| 3.0.0-preview.9 | 81 | 1/14/2026 |