Toralux.Open.IdentityServer.Admin.EntityFramework.Shared 0.2.2

dotnet add package Toralux.Open.IdentityServer.Admin.EntityFramework.Shared --version 0.2.2
                    
NuGet\Install-Package Toralux.Open.IdentityServer.Admin.EntityFramework.Shared -Version 0.2.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Toralux.Open.IdentityServer.Admin.EntityFramework.Shared" Version="0.2.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Toralux.Open.IdentityServer.Admin.EntityFramework.Shared" Version="0.2.2" />
                    
Directory.Packages.props
<PackageReference Include="Toralux.Open.IdentityServer.Admin.EntityFramework.Shared" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Toralux.Open.IdentityServer.Admin.EntityFramework.Shared --version 0.2.2
                    
#r "nuget: Toralux.Open.IdentityServer.Admin.EntityFramework.Shared, 0.2.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Toralux.Open.IdentityServer.Admin.EntityFramework.Shared@0.2.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Toralux.Open.IdentityServer.Admin.EntityFramework.Shared&version=0.2.2
                    
Install as a Cake Addin
#tool nuget:?package=Toralux.Open.IdentityServer.Admin.EntityFramework.Shared&version=0.2.2
                    
Install as a Cake Tool

Toralux Open IdentityServer Admin

Toralux Open.IdentityServer Admin

Modern administration UI for Open IdentityServer and ASP.NET Core Identity

Manage IdentityServer clients and resources, ASP.NET Core Identity users and roles, configuration health, auditing, and security from one modern interface.

.NET React License Discord

Installation · Local Development · Docker · Roadmap · Upstream Discord

Toralux Open IdentityServer Admin dashboard

Toralux fork — synced to upstream 3.1.0

Toralux Open IdentityServer Admin is a fork of skoruba/Duende.IdentityServer.Admin — forked at v3.0.0 (commit 45da4dc4), synced to upstream 3.1.0 (commit 22c84428) — retargeted from Duende IdentityServer to Open IdentityServer. Packages ship as Toralux.Open.IdentityServer.Admin.*; upstream lineage and the divergences this fork intentionally keeps are documented in CHANGELOG.md and NOTICE.

Not affiliated with or endorsed by Rock Solid Knowledge / IdentityServer.com. "Duende IdentityServer" is a trademark of Duende Software; "IdentityServer" is a trademark of Rock Solid Knowledge Ltd. This project is an independent administration UI for the open-source Open IdentityServer.

What's in this UI

A completely redesigned administration experience built with React, TypeScript, Tailwind CSS, shadcn/ui, and .NET 10.

See the roadmap and changelog for release history and upcoming features.


Highlights

Area Highlights
🧭 New Admin UI React, TypeScript, Tailwind CSS, and shadcn/ui
⚙️ Modern backend .NET 10 and Open IdentityServer 7.4.7
📊 Monitoring Dashboards, configuration rules, and issue tracking
🧙 Client management Improved workflows and guided client creation wizard
🔐 Authentication Passkey support in STS Identity
🧩 Mapping Mapperly-based mapping pipeline and customization points
🛡️ Security Hardened audit logging and stronger validation
🧪 Quality Expanded Playwright UI, Admin API, STS, repository, and audit test coverage

Contents


Administration UI Preview

Explore the redesigned administration experience, built with Tailwind CSS and shadcn/ui components.

🌙 Dashboard (Dark)

Admin-preview

🧙‍♂️ Client Creation – Wizard Flow

Admin-Client-Wizard

💼 Client Management

Admin-Client-Edit

📡 Monitoring

Define and track configuration rules for clients, API resources, and identity resources:

  • Flag deprecated OAuth 2.1 flows
  • Enforce required scopes
  • Validate naming conventions
  • Warn about expired client secrets
🧱 Configuration Rules

Configuration-Rules

🧩 Configuration Issues

Configuration-Issues

Solution Structure

Project structure


✅ Prerequisites

  • .NET 10 SDK
  • Node.js 22.12+ and npm (required for the React client)
  • SQL Server (default LocalDB) or PostgreSQL
  • Open IdentityServer 7.4.7

Note: Using older .NET versions may cause 502.5 errors on IIS or application startup failures.


📦 Installation via dotnet new Template

🔒 Database note:
This template includes default EF migrations. Review them and back up your database before applying.

ℹ️ Migration note from IdentityServer4.Admin:
The UserSecretsId for Admin, Admin API, and STS projects remains the same as in the older Skoruba.IdentityServer4.Admin solution to ease config migration. If you still have secrets from the old project on your machine, they will be reused (e.g., ApplySeed could point at your old DB). Change or clear user secrets if you need isolation.

1. Install the template

dotnet new install Toralux.Open.IdentityServer.Admin.Templates::0.1.0

2. Create a new project

dotnet new toralux.open-isadmin \
  --name MyProject \
  --title MyProject \
  --adminemail "admin@example.com" \
  --adminpassword "Passw0rd-123" \
  --adminrole MyRole \
  --adminclientid MyClientId \
  --adminclientsecret MyClientSecret \
  --dockersupport true \
  --requirepushedauthorization true

Template Options

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 false). Note: Pushed Authorization Requests require Duende IdentityServer Business Edition upstream and are not used by Open IdentityServer. More info

🚀 Quick Start – Local Development

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 Toralux.Open.IdentityServer.STS.Identity IdentityServer + authentication
Admin API Toralux.Open.IdentityServer.Admin.Api REST API backend
Admin UI Toralux.Open.IdentityServer.Admin SPA host

1. Clone the repository

git clone https://github.com/toralux/Open.IdentityServer.Admin
cd Open.IdentityServer.Admin

2. Install React dependencies (first run only)

cd src/Toralux.Open.IdentityServer.Admin.UI.Client
npm install
cd ../..

3. Run the services

Open three terminals and run:

# Terminal 1: STS (IdentityServer)
cd src/Toralux.Open.IdentityServer.STS.Identity
dotnet run

# Terminal 2: Admin API
cd src/Toralux.Open.IdentityServer.Admin.Api
dotnet run

# Terminal 3: Admin UI Host
cd src/Toralux.Open.IdentityServer.Admin
dotnet run

4. Default local URLs

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).


🐳 Running via Docker (Optional)

Tip: For the fastest onboarding, use the dotnet run approach above. Docker requires custom domain and certificates.

DNS Configuration

Update your hosts file to resolve toralux.local:

Windows: C:\Windows\System32\drivers\etc\hosts
Linux / macOS: /etc/hosts

127.0.0.1 toralux.local sts.toralux.local admin.toralux.local admin-api.toralux.local

Certificates Setup

Use mkcert to generate self-signed local certificates.

Windows
cd shared/nginx/certs
mkcert --install
copy $env:LOCALAPPDATA\mkcert\rootCA-key.pem ./cacerts.pem
copy $env:LOCALAPPDATA\mkcert\rootCA.pem ./cacerts.crt

# Generate toralux.local certificates
mkcert -cert-file toralux.local.crt -key-file toralux.local.key toralux.local *.toralux.local
mkcert -pkcs12 toralux.local.pfx toralux.local *.toralux.local
macOS / Linux
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 toralux.local certificates
mkcert -cert-file toralux.local.crt -key-file toralux.local.key toralux.local *.toralux.local
mkcert -pkcs12 toralux.local.pfx toralux.local *.toralux.local

Run Docker Compose

docker-compose build
docker-compose up -d

Docker setup is based on bravecobra's repository – thanks! 😊

Docker Images

Docker images are available on Docker Hub.

To publish images, check build/publish-docker-images.ps1 and update the profile name.


🗄️ EF Core & Data Access

DbContexts

The solution uses the following DbContext classes:

  • AdminIdentityDbContext – ASP.NET Core Identity data
  • AdminLogDbContext – Logging data
  • IdentityServerConfigurationDbContext – IdentityServer configuration store
  • IdentityServerPersistedGrantDbContext – IdentityServer operational store
  • AuditLoggingDbContext – Audit logging
  • IdentityServerDataProtectionDbContext – Data protection keys
  • AdminConfigurationDbContext – Admin configuration and monitoring (added in v3.0.0)

Database Providers

  • SQL Server (default)
  • PostgreSQL

Switch providers in appsettings.json:

"DatabaseProviderConfiguration": {
  "ProviderType": "SqlServer"
}

Connection String Examples

Seven connection strings are used. Beyond the six obvious ones (ConfigurationDbConnection, PersistedGrantDbConnection, IdentityDbConnection, AdminLogDbConnection, AdminAuditLogDbConnection, DataProtectionDbConnection), hosts also read AdminConfigurationDbConnection (Admin UI configuration storage). When overriding per environment (env vars like ConnectionStrings__AdminConfigurationDbConnection, Key Vault, etc.), override all seven — missing the seventh causes hard-to-diagnose startup failures.

SQL Server (LocalDB):

Data Source=(LocalDb)\\MSSQLLocalDB;database=DuendeIdentityServerAdmin;trusted_connection=yes;

PostgreSQL:

Server=localhost;Port=5432;Database=DuendeIdentityServerAdmin;User Id=sa;Password=#;

Running Entity Framework Migrations

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

Migrating from Skoruba/Duende Admin? Open.IdentityServer seed secrets hash as BASE64 (Duende.IdentityModel ToSha256), not the IS4-style lowercase hex SHA-256. Client secrets seeded or imported with hex hashes will not authenticate — re-hash (BASE64) or re-seed them when moving data from a Skoruba/Duende database.

Seed data is configured in:

  • identityserverdata.json – IdentityServer clients and resources
  • identitydata.json – ASP.NET Core Identity users and roles

Enable seeding via:

Option 1: Command line

dotnet run /seed

Option 2: Configuration (appsettings.json)

"SeedConfiguration": {
  "ApplySeed": true
},
"DatabaseMigrationsConfiguration": {
  "ApplyDatabaseMigrations": true
}

🔐 Authentication & Authorization

  • Admin policy: AuthorizationConsts.AdministrationPolicy
  • Required role configured in AdministrationRole (appsettings.json)
  • Admin UI authenticates via OIDC against STS
  • Admin UI calls Admin API using client credentials

Configuration in appsettings.json:

"AdministrationRole": "ToraluxIdentityAdminAdministrator"

🔑 Azure Key Vault Integration

Azure Key Vault supports:

  • Configuration secrets
  • Data Protection keys
  • IdentityServer signing certificates

Configuration

"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).

Data Protection

"DataProtectionConfiguration": {
  "ProtectKeysWithAzureKeyVault": true
},
"AzureKeyVaultConfiguration": {
  "DataProtectionKeyIdentifier": "https://your-vault.vault.azure.net/keys/dataprotection"
}

IdentityServer Signing Certificate

"AzureKeyVaultConfiguration": {
  "IdentityServerCertificateName": "IdentityServerSigningCert"
}

📝 Logging

Uses Serilog with the following sinks (configured in serilog.json):

  • Console
  • File
  • MSSqlServer
  • Seq

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"
        }
      }
    ]
  }
}

📊 Audit Logging

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));

🔌 External Authentication Providers

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


📧 Email Service

SendGrid

"SendgridConfiguration": {
  "ApiKey": "",
  "SourceEmail": "",
  "SourceName": ""
}

SMTP

"SmtpConfiguration": {
  "From": "",
  "Host": "",
  "Login": "",
  "Password": ""
}

🏥 Health Checks

All services expose a /health endpoint for monitoring:

  • Admin UI: https://localhost:7127/health
  • Admin API: https://localhost:44302/health
  • STS: https://localhost:44310/health

Checks include:

  • Database connectivity
  • IdentityServer availability

🌍 Localization

Translations are stored in /i18n.

Currently supported:

  • English

Contributing translations:
Feel free to submit a PR with your translation! 😊


🧪 API & Swagger

Swagger UI is available at:

https://localhost:44302/swagger

Configuration (appsettings.json):

"AdminApiConfiguration": {
  "IdentityServerBaseUrl": "https://localhost:44310",
  "OidcSwaggerUIClientId": "toralux_identity_admin_api_swaggerui",
  "OidcApiName": "toralux_identity_admin_api"
}

⚙️ STS Configuration

Login Method

Choose between Username or Email login:

"LoginConfiguration": {
  "ResolutionPolicy": "Username"
}

User Registration

Enable or disable user registration:

"RegisterConfiguration": {
  "Enabled": true
}

🧩 Identity Mapping Customization

Identity DTO/entity mapping in Toralux.Open.IdentityServer.Admin.BusinessLogic.Identity is handled by IdentityDataMapper.

By default:

  • Standard ASP.NET Core Identity fields are mapped explicitly.
  • Additional custom fields are mapped automatically when DTO and entity use the same property name and compatible type.
  • Internal Identity fields (PasswordHash, SecurityStamp, ConcurrencyStamp, NormalizedUserName, NormalizedEmail) are protected during DTO → entity updates.

1. Same-name custom properties

If your custom UserDto / RoleDto and IdentityUser / IdentityRole share the same custom property name, no extra configuration is needed.

2. Different property names (customizers)

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 your custom user DTO exposes additional audit-sensitive fields, also implement IIdentityUserAuditSanitizer<TUserDto> on the user mapping customizer. The built-in audit sanitizer always redacts PasswordHash, SecurityStamp, and ConcurrencyStamp by property name.

3. Full mapper override

If you need full control, replace the default IIdentityDataMapper<...> registration in DI with your own implementation after calling AddAdminAspNetIdentityServices. Custom mapper implementations do not need to implement audit sanitization for backward compatibility, but they can implement IIdentityAuditDataMapper<TUserDto, TUsersDto> when they need custom audit redaction. Without it, audit logging falls back to the built-in redaction for PasswordHash, SecurityStamp, and ConcurrencyStamp.


📚 Solution Overview

The solution contains unit and integration tests for all major components.

STS

Toralux.Open.IdentityServer.STS.Identity – IdentityServer with ASP.NET Core Identity

Admin API

Toralux.Open.IdentityServer.Admin.Api – REST API with Swagger

Admin UI

  • Toralux.Open.IdentityServer.Admin – .NET host
  • Toralux.Open.IdentityServer.Admin.UI – UI services
  • Toralux.Open.IdentityServer.Admin.UI.Spa – Precompiled React assets
  • Toralux.Open.IdentityServer.Admin.UI.Client – React source code

Business Logic

  • Toralux.Open.IdentityServer.Admin.BusinessLogic – IdentityServer DTOs, services, repositories
  • Toralux.Open.IdentityServer.Admin.BusinessLogic.Identity – Identity DTOs, services, repositories
  • Toralux.Open.IdentityServer.Admin.BusinessLogic.Shared – Shared logic

Entity Framework

  • Toralux.Open.IdentityServer.Admin.EntityFramework – Core EF entities
  • Toralux.Open.IdentityServer.Admin.EntityFramework.Configuration – Entity configurations
  • Toralux.Open.IdentityServer.Admin.EntityFramework.Extensions – EF extensions
  • Toralux.Open.IdentityServer.Admin.EntityFramework.Identity – Identity repositories
  • Toralux.Open.IdentityServer.Admin.EntityFramework.Shared – DbContexts
  • Toralux.Open.IdentityServer.Admin.EntityFramework.SqlServer – SQL Server migrations
  • Toralux.Open.IdentityServer.Admin.EntityFramework.PostgreSQL – PostgreSQL migrations

Shared

  • Toralux.Open.IdentityServer.Shared – Shared DTOs
  • Toralux.Open.IdentityServer.Shared.Configuration – Shared configuration

Tests

  • Toralux.Open.IdentityServer.Admin.UnitTests – Unit tests
  • Toralux.Open.IdentityServer.Admin.Api.IntegrationTests – API integration tests
  • Toralux.Open.IdentityServer.STS.IntegrationTests – STS integration tests
  • Toralux.Open.IdentityServer.Admin.UI.Client.IntegrationTests – Playwright UI integration tests (OIDC login flow + Admin UI assertions)

UI Integration Tests (Playwright)

The UI E2E test project is located in:

  • tests/Toralux.Open.IdentityServer.Admin.UI.Client.IntegrationTests

To run it:

cd tests/Toralux.Open.IdentityServer.Admin.UI.Client.IntegrationTests
npm install
npx playwright install chromium
npm test

Default expected runtime services:

  • STS: https://localhost:44310
  • Admin API: https://localhost:44302
  • Admin UI host:
    • Kestrel-hosted app: https://localhost:7127
    • Vite dev server / default E2E_ADMIN_URL for Playwright: https://localhost:50445

Important: The seeded OIDC client redirect URIs and CORS origins in src/Toralux.Open.IdentityServer.Admin.Api/identityserverdata.json use https://localhost:50445 by default. If you run the Admin UI on https://localhost:7127 instead, update the client configuration (or the Playwright E2E_ADMIN_URL) so redirects and CORS validation continue to work.

The tests load credentials and expected client data from seed files:

  • src/Toralux.Open.IdentityServer.Admin.Api/identitydata.json
  • src/Toralux.Open.IdentityServer.Admin.Api/identityserverdata.json

🚦 Roadmap & Changelog

For detailed release history and upcoming features, see CHANGELOG.md.

Fork roadmap:

  • Playwright E2E spec-sync (specs drifted from the SPA during the retarget)
  • Single-glyph package icon variant for better 32px legibility
  • Track upstream skoruba releases — absorbed via the documented replay workflow in CONTRIBUTING.md
  • Track Open.IdentityServer releases (server-side sessions and PAR are on their roadmap)

For the upstream project's own roadmap (3.x–6.x plans: DTO refactoring, claims management UI, Minimal API rewrite), see their README.


Releasing

Publishing is fully tag-driven via the publish workflow:

  • Prerelease (beta): push a tag like v0.2.0-beta.1 — packages publish as prerelease versions (0.2.0-beta.1), visible on NuGet only with --prerelease.
  • Stable: push v0.2.0 — same pipeline, standard visibility.
  • The tag is the single source of truth for the version — no manual version bumps.
  • Convention: beta tags for upstream-sync releases and anything not yet proven in the wild; stable tags after a beta has cooked (or for trivially safe fixes).

Auth is keyless via nuget.org trusted publishing: the workflow exchanges a GitHub OIDC token for a 1-hour API key — no NUGET_API_KEY secret to store or rotate. Requires a one-time policy on nuget.org (username → Trusted Publishing → this repo + publish.yml).

📜 License

This repository is licensed under Apache License 2.0.

Open.IdentityServer — the framework this admin UI targets — is likewise licensed under Apache 2.0. There is no commercial license, no RPL, and no production licensing requirement for either project.

This project includes code with deep lineage, originally derived from DuendeSoftware/IdentityServer.Quickstart.UI (Apache 2.0) via the upstream admin project.


🙏 Acknowledgements

This project is a community fork and would not exist without:


📧 Contact & Support

Maintainer: Tor Anders Johansen (@toralux)

Feedback is welcome — please open an issue on this repository.

Supporting the upstream

The original admin project is maintained by Jan Škoruba. If this fork saved you time, consider supporting him directly:

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Toralux.Open.IdentityServer.Admin.EntityFramework.Shared:

Package Downloads
Toralux.Open.IdentityServer.Admin.EntityFramework.Admin

Entity Framework layer for admin features

Toralux.Open.IdentityServer.Admin.BusinessLogic.Identity

Business Logic layer for the administration of the Asp.Net Core Identity and Open IdentityServer

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.2 0 9/23/2026
0.1.8 112 9/18/2026
0.1.0 110 9/17/2026