Setting Up and Hosting IdentityServer
When to Use This Skill
- Setting up a new Duende IdentityServer project from scratch
- Configuring the ASP.NET Core DI system and middleware pipeline for IdentityServer
- Deciding between separate vs shared hosting patterns
- Integrating IdentityServer with ASP.NET Identity for user management
- Configuring
IdentityServerOptions(issuer, key management, endpoints) - Setting up proxy/load balancer forwarded headers
- Configuring data protection for production deployments
- Understanding the IdentityServer middleware pipeline ordering
Docs: https://docs.duendesoftware.com/identityserver/fundamentals
Core Concepts
Duende IdentityServer is middleware that adds OpenID Connect and OAuth 2.0 endpoints to an ASP.NET Core host. It requires two setup steps: registering services in DI and adding middleware to the request pipeline.
Architecture Decision: Separate vs Shared Host
IdentityServer should be in its own dedicated application to minimize the attack surface. While it is technically possible to co-host IdentityServer with clients or APIs, this is not recommended.
Step 1: Install Templates and Create a Project
The duende-is-empty template creates a minimal project with the IdentityServer NuGet package installed and basic configuration.
Step 2: Register IdentityServer Services (DI)
Call AddIdentityServer on the service collection to register all necessary services. This method also calls AddAuthentication internally.
Adding Configuration Stores
The builder object returned by AddIdentityServer provides extension methods to add configuration stores for clients, resources, and scopes:
Store options:
- In-memory stores - good for development, demos, and static configuration
- EntityFramework stores - production-ready, supports dynamic configuration
- Custom stores - implement the store interfaces for any backing store
Minimal Working Example
Step 3: Configure the Request Pipeline
Add UseIdentityServer middleware to the pipeline. Pipeline ordering is critical.
Pipeline Ordering Rules
Common Pipeline Anti-Patterns
Step 4: Configure Essential IdentityServerOptions
Key Configuration Properties
Step 5: Configure the License Key
Duende IdentityServer requires a valid license for production use. Without a license key, IdentityServer runs in trial/community mode and will log a warning on startup.
Set the license key via options.LicenseKey or via configuration:
Store the key in a secret manager, environment variable, or key vault — never in source-controlled appsettings.json.
Step 6: ASP.NET Identity Integration
To use ASP.NET Identity as the user store for IdentityServer, install the integration package and configure both systems:
What AddAspNetIdentity Configures
AddAspNetIdentity<TUser> registers the following IdentityServer implementations:
IProfileService- usesIUserClaimsPrincipalFactoryto add claims to tokensIResourceOwnerPasswordValidator- supports the password grant typeIUserClaimsPrincipalFactory- a wrapper implementation that calls through to the previously registered factory and adds extra IdentityServer-specific claims
Custom IUserClaimsPrincipalFactory
If you register a custom IUserClaimsPrincipalFactory before calling AddAspNetIdentity, the IdentityServer registration will resolve your factory and call through to it, layering additional claims on top:
Inactive User Handling
ASP.NET Identity has no built-in concept of inactive users. The default IsActiveAsync implementation returns true. To support enable/disable functionality:
Template Alternative
Use the duende-is-aspid template for a pre-configured ASP.NET Identity integration:
Production Deployment: Proxy and Load Balancer Configuration
When behind a reverse proxy or load balancer, the proxy obscures request scheme and IP address. This causes common symptoms:
- HTTPS downgraded to HTTP in discovery document
- Incorrect host names in discovery or redirects
- Cookies missing the
secureattribute
Solution: Forwarded Headers Middleware
Option 1: Environment variable (simple)
Set ASPNETCORE_FORWARDEDHEADERS_ENABLED=true for cloud/Kubernetes environments.
Option 2: Explicit configuration (production)
Add UseForwardedHeaders() early in the pipeline, before UseIdentityServer().
Production Deployment: Data Protection
Data protection is critical for IdentityServer. It protects signing keys at rest, persisted grants, server-side sessions, and authentication cookies. See ASP.NET Core Data Protection for comprehensive guidance covering all Duende SDKs.
Data Protection Checklist
Data Protection Keys vs Signing Keys
These are completely separate:
Common Pitfalls
-
Missing
UseAuthorization()- The Duende UI template requires authorization middleware. Omitting it causes authorization failures in the UI pages. -
Redundant
UseAuthentication()-UseIdentityServer()already includesUseAuthentication(). Adding both is unnecessary but not harmful. -
Data protection not configured for production - The default file-based key storage does not survive container restarts or work across load-balanced instances. Always configure persistent, shared key storage.
-
Issuer mismatch - If
IssuerUriis set manually, clients must know this exact value. Prefer letting IdentityServer infer the issuer from request URLs. -
Keys directory in source control - The
~/keysdirectory created by automatic key management contains cryptographic secrets and must be excluded from source control via.gitignore. -
Shared hosting with APIs/clients - Co-hosting IdentityServer with other applications increases the attack surface. Use a dedicated host.
-
Not calling
AddAspNetIdentityafterAddIdentity- When using ASP.NET Identity, you must call both.AddIdentityconfigures ASP.NET Identity;AddAspNetIdentitybridges it to IdentityServer.
Related Skills
identityserver-configuration— client definitions, resources, scopesidentityserver-deployment— production deployment, data protection, health checksidentityserver-aspire— orchestrating IdentityServer in Aspire AppHost


