Skip to content

TheIdServer Duende Web Server

TheIdServer use Duende IdentityServer, for a commercial use you need to acquire a license.

The server obtains configuration from appsettings.json, appsettings.{Environment}.json, command-line arguments, or environment variables.

Read Configuration in ASP.NET Core for more information.

Installation

From Terraform

The Terraform Helm module theidserver make the deployement of TheIdServer easy.
To deploy the Duende version choose the aguacongas/theidserver.duende image.

provider "helm" {
  kubernetes {
    config_path = var.kubeconfig_path
  }
}

module "theidserver" {
  source = "Aguafrommars/theidserver/helm"

  host = "theidserver.com"
  tls_issuer_name = "letsencrypt"
  tls_issuer_kind = "ClusterIssuer"

  image = {
    repository = "aguacongas/theidserver.duende"
    pullPolicy = "Always"
    tag = "next"
  }
}

From Helm

The theidserver Helm chart is available in hub.helm.sh.

Install

helm repo add aguafrommars https://aguafrommars.github.io/helm
helm install aguafrommars theidserver --set theidserver.mysql.db.password=my-P@ssword --set image.repository=aguacongas/theidserver.duende

By default the helm char install the IS4 version, to install the Duende version your need to set image.repository=aguacongas/theidserver.duende.

Upgrade

Follow upgrades intstructions in the chart readme.

From Docker

A server's Linux image is available on Docker Hub.

sample/MultiTiers/Aguacongas.TheIdServer.Private/Dockerfile.Duende-private demonstrates how to create an image from the server image to run a private Linux server container.

sample/MultiTiers/Aguacongas.TheIdServer.Public/Dockerfile.Duende-public illustrates how to create an image from the server image to run a public Linux server container.

Read Hosting ASP.NET Core images with Docker over HTTPS to set up the HTTPS certificate.

Kubernetes sample

/sample/Kubernetes/README.md contains a sample to set up a solution with Kubernetes.

The sample use the IS4 version but you just need to use aguacongas/theidserver.duende as docker image in the deployement file.

From dotnet new template

The template TheIdServer.Duende.Template can be use to setup a TheIdServer solution.

Install

dotnet new -i TheIdServer.Duende.Template

Use

> dotnet new tisduende -o TheIdServer
The template "TheIdServer.Duende" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on TheIdServer\TheIdServer.sln...
  Determining projects to restore...
  Restored C:\Projects\Perso\Templates\artifacts\TheIdServer\test\WebAssembly.Net.Http\WebAssembly.Net.Http.csproj (in 114 ms).
  Restored C:\Projects\Perso\Templates\artifacts\TheIdServer\src\TheIdServer.BlazorApp\TheIdServer.BlazorApp.csproj (in 916 ms).
  Restored C:\Projects\Perso\Templates\artifacts\TheIdServer\test\Microsoft.AspNetCore.Components.Testing\Microsoft.AspNetCore.Components.Testing.csproj (in 1.08 sec).
  Restored C:\Projects\Perso\Templates\artifacts\TheIdServer\src\TheIdServer\TheIdServer.csproj (in 2.03 sec).
  Restored C:\Projects\Perso\Templates\artifacts\TheIdServer\test\TheIdServer.Test\TheIdServer.Test.csproj (in 2.04 sec).
  Restored C:\Projects\Perso\Templates\artifacts\TheIdServer\test\TheIdServer.IntegrationTest\TheIdServer.IntegrationTest.csproj (in 2.04 sec).
Restore succeeded.

From NuGet Packages

If you need more customization, you can use published NuGet packages.
sample/MultiTiers contains a sample to build server and API from NuGet packages.

The sample use IS4 version but you just need to remplace IS4 by Duende in package reference to use the Duende version.

From Github Release

Choose your release in the list of releases and download the server zip.
Unzip in the destination of your choice. Unzip in the destination of your choice. As with any ASP.NET Core web site, it can run in IIS or as a stand-alone server using your chosen platform.

Read Host and deploy ASP.NET Core for more information.

Configure data protection

Data protection provides details on data protection configuration.

Configure site

The site name is defined by SiteOptions:TheIdServer.

"SiteOptions": {
  "Name": "TheIdServer"
}

The site stylecheets are wwwroot/lib/bootstrap/css/bootstrap.css and wwwroot/css/site.min.css.
The site logo is wwwroot/logo.png.
And the favicon is wwwroot/favicon.ico.

By replacing those files you can redefined the site style by yours.

Configure account options

The section AccountOptions is bound to AccountOptions.

"AccountOptions": {
  "AllowLocalLogin": true,
  "AllowRememberLogin": true,
  "RememberMeLoginDuration": "30.00:00:00",
  "ShowLogoutPrompt": true,
  "AutomaticRedirectAfterSignOut": false,
  "InvalidCredentialsErrorMessage": "Invalid username or password",
  "ShowForgotPassworLink": true,
  "ShowRegisterLink": true,
  "ShowResendEmailConfirmationLink": true
}

Configure ASP.Net Core Identity options

The section IdentityOptions is bound to the class Microsoft.AspNetCore.Identity.IdentityOptions.
So you can set any ASP.Net Core Identity options you want from configuration

"IdentityOptions": {
  "User": {
    "AllowedUserNameCharacters": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+ "
  },
  "SignIn": {
    "RequireConfirmedAccount": true
  }
}

Configure password hashers options

Read OWASP Password Storage Cheat Sheet to choose and configure your password hasher.

PBKDF2 Password hasher

Microsoft.AspNetCore.Identity.PasswordHasher is the default hasher used by ASP.Net Core Identity.
You can hash password using PBKDF2 if the upgrade password hasher is configured to use Microsoft.AspNetCore.Identity.PasswordHasher.

The section PasswordHasherOptions is bound to the class Microsoft.AspNetCore.Identity.PasswordHasherOptions.
So you can set any Microsoft.AspNetCore.Identity.PasswordHasherOptions properties you want from configuration.

"PasswordHasherOptions": {
    "IterationCount": 600000
}

Argon2id password hasher

You can hash password using Argon2id if the upgrade password hasher is configured to use Aguacongas.TheIdServer.Identity.Argon2PasswordHasher.Argon2PasswordHasher.

The section Argon2PasswordHasherOptions is bound to the class Aguacongas.TheIdServer.Identity.Argon2PasswordHasher.Argon2PasswordHasherOptions.
So you can set any Aguacongas.TheIdServer.Identity.Argon2PasswordHasher.Argon2PasswordHasherOptions properties you want from configuration.

"Argon2PasswordHasherOptions": {
    "Interations": 2,
    "Memory": 67108864
}

scrypt password hasher

You can hash password using scrypt if the upgrade password hasher is configured to use Aguacongas.TheIdServer.Identity.ScryptPasswordHasher.ScryptPasswordHasher.

The section ScryptPasswordHasherOptions is bound to the class Aguacongas.TheIdServer.Identity.ScryptPasswordHasher.ScryptPasswordHasherOptions.
So you can set any Aguacongas.TheIdServer.Identity.ScryptPasswordHasher.ScryptPasswordHasherOptions properties you want from configuration.

"ScryptPasswordHasherOptions": {
    "IterationCount": 131072,
    "BlockSize": 8,
    "ThreadCount": 1
}

bcrypt password hasher

You can hash password using bcrypt if the upgrade password hasher is configured to use Aguacongas.TheIdServer.Identity.BcryptPasswordHasher.BcryptPasswordHasher.

The section BcryptPasswordHasherOptions is bound to the class Aguacongas.TheIdServer.Identity.BcryptPasswordHasher.BcryptPasswordHasherOptions.
So you can set any Aguacongas.TheIdServer.Identity.BcryptPasswordHasher.BcryptPasswordHasherOptions properties you want from configuration.

"BcryptPasswordHasherOptions": {
    "WorkFactor": 11
}

Upgrade password hasher

Upgrade password hasher is used to manage hash migration between old password hashing algorithm to the new one to use.
In previous version of TheIdServer password was hashed with PBKDF2 by default ASP.Net Core Identity password hasher with its default configuration.
Now you can choose between Argon2id, scrypt, bcrypt and PBKDF2 by settings the hasher to use.

Read Password Hasher to rehash password to a new algorithm for ASP.NET Core Identity. for more information.

The section UpgradePasswordHasherOptions is bound to the class Aguacongas.TheIdServer.Identity.UpgradePasswordHasher.UpgradePasswordHasherOptions.
So you can set any Aguacongas.TheIdServer.Identity.UpgradePasswordHasher.UpgradePasswordHasherOptions properties you want from configuration.

"UpgradePasswordHasherOptions": {
    "HashPrefixMaps": {
      "0": "Microsoft.AspNetCore.Identity.PasswordHasher",
      "1": "Microsoft.AspNetCore.Identity.PasswordHasher",
      "162": "Aguacongas.TheIdServer.Identity.Argon2PasswordHasher.Argon2PasswordHasher",
      "12": "Aguacongas.TheIdServer.Identity.ScryptPasswordHasher.ScryptPasswordHasher",
      "188": "Aguacongas.TheIdServer.Identity.BcryptPasswordHasher.BcryptPasswordHasher"
    },
    "UsePasswordHasherTypeName": "Aguacongas.TheIdServer.Identity.Argon2PasswordHasher.Argon2PasswordHasher"
}

Configure Duende IdentityServer

The section IdentityServerOptions is bound to the class Duende.IdentityServer.Configuration.IdentityServerOptions.
So you can set any Duende IdentityServer options you want from configuration (but key management options).

"IdentityServerOptions": {
  "Events": {
    "RaiseErrorEvents": true,
    "RaiseInformationEvents": true,
    "RaiseFailureEvents": true,
    "RaiseSuccessEvents": true
  },
  "Endpoints": {
    "EnableJwtRequestUri": true
  }
}

Discovery document customs entries

You can add customs entries to the genererated discovery document with IdentityServerOptions sub section CustomEntriesOfStringArray, CustomEntriesOfString and CustomEntriesOfBool

"IdentityServerOptions": {
  "CustomEntriesOfStringArray": {
    "token_endpoint_auth_signing_alg_values_supported": [
      "RS256",
      "ES256",
      "ES384",
      "ES512",
      "PS256",
      "PS384",
      "PS512",
      "RS384",
      "RS512"
    ]
  }
}

The sample above will add "token_endpoint_auth_signing_alg_values_supported" node to the generated document.

Mutual TLS client certificate options

When Muutal TLS is enabled, you can configure the client certificate authentication options with CertificateAuthenticationOptions section.

"IdentityServerOptions": {
    "MutualTls": {
      "Enabled": true
    }
},
"CertificateAuthenticationOptions": {
  "AllowedCertificateTypes": "All",
  "ValidateCertificateUse": false,
  "ValidateValidityPeriod": false,
  "RevocationMode": "NoCheck"
}

Retrieves client certificates fron HTTP request header

When Mutual TLS is enabled the client certificate can be read in PEM format from request header. For exemple if you use a kubernetes NGINX ingress you can configure it to send the client certificate to the backend in the ssl-client-cert header.
See Client Certificate Authentication.

To retrieve the client certificate from the request header confiure the MutualTls sub section like :

"IdentityServerOptions": {
    "MutualTls": {
      "Enabled": true,
      "PEMHeader": "ssl-client-cert"
    }
}

Configure Server-side sessions

Read Server-side sessions

Configure stores

Using Entity Framework Core

The server supports SqlServer, Sqlite, MySql, PostgreSQL, Oracle, and InMemory databases.
Use DbType to the define the database engine.

"DbType": "SqlServer"

And ConnectionStrings:DefaultConnection to define the connection string.

"ConnectionStrings": {
  "DefaultConnection": "Data Source=(LocalDb)\\MSSQLLocalDB;database=TheIdServer;trusted_connection=yes;"
}

A devart dotConnect for Oracle license is a requirement for Oracle.

Using RavenDb

Use DbType to the define the RavenDb database engine.

"DbType": "RavenDb"

And RavenDbOptions to define the RavenDb options.

"RavenDbOptions": {
  "Urls": [
    "https://a.ravendb.local",
    "https://b.ravendb.local",
    "https://c.ravendb.local"
  ],
  "Database": "TheIdServer",
  "CertificatePath": "cluster.admin.client.certificate.pfx",
  "CertificatePassword": "p@$$w0rd"
}

As no DbContext will be registered, you cannot store signing keys in EF but you can choose the RavenDb storage kind (see Configure signin keys):

"IdentityServer": {
  "Key": {
    "StorageKind": "RavenDb"
  }
},
"DataProtectionOptions": {
  "StorageKind": "RavenDb"
}

The server support RavenDb 4.1 and above.

Using MongoDb

Use DbType to the define the RavenDb database engine.

"DbType": "MongoDb"

And ConnectionStrings:DefaultConnection to define the connection string.

"ConnectionStrings": {
  "DefaultConnection": "mongodb+srv://theidserver:theidserverpwd@cluster0.fvkfz.mongodb.net/TheIdServer?retryWrites=true&w=majority"
}

We cannot used another database than the default database defined in the connection string.

As no DbContext will be registered, you cannot store signing keys in EF but you can choose the MongoDb storage kind (see Configure signin keys):

"IdentityServer": {
  "Key": {
    "StorageKind": "MongoDb"
  }
},
"DataProtectionOptions": {
  "StorageKind": "MongoDb"
}

Using the API

public-private.svg

If you don't want to expose a database with your server, you can set up a second server on a private network accessing the database and use this private server API to access data.

"Proxy": true,
"PrivateServerAuthentication": {
  "Authority": "https://theidserverprivate",
  "ApiUrl": "https://theidserverprivate/api",
  "ClientId": "public-server",
  "ClientSecret": "84137599-13d6-469c-9376-9e372dd2c1bd",
  "Scope": "theidserveradminapi",
  "HttpClientName": "is4"
},
"SignalR": {
  "HubUrl": "https://theidserverprivate/providerhub"
  "HubOptions": {
    "EnableDetailedErrors": true
  },
  "UseMessagePack": true
}

Proxy

Start the server with proxy mode enabled.

PrivateServerAuthentication

Defines how to authenticate the public server on private server API.

SignalR

Defines the SignalR client configuration.
This client is used to update the external provider configuration of a running instance. When an external provider configuration changes, the API sends a SignalR notification to inform other running instances.

For more information, read Load balancing scenario.

The SignalR hub accepts requests at /providerhub and supports the MessagePack protocol.

For more information, read Use MessagePack Hub Protocol in SignalR for ASP.NET Core.

Database migration and data seeding

Starting the server with the /seed command-line argument creates the database with initial data. Alternatively, configure the server with the following to create a database with initial users, protected resources, identity resources, and clients.

"Migrate": true,
"Seed": true

Roles

  • Is4-Writer authorizes users in this role to write data.
  • Is4-Reader permits users in this role to read data.

Identity resources

  • profile default profile resource with role claim
  • openid default OpenID resource
  • address default address resource
  • email default email resource
  • phone default phone resource

Users

Users defined in InitialData:Users configuration section are loaded and stored to the DB.

Default configuration:

"InitialData": {
...
 "Users": [
    {
      "UserName": "alice",
      "Email": "alice@theidserver.com",
      "EmailConfirmed": true,
      "PhoneNumber": "+41766403736",
      "PhoneNumberConfirmed": true,
      "Password": "Pass123$",
      "Roles": [
        "Is4-Writer",
        "Is4-Reader"
      ],
      "Claims": [
        {
          "ClaimType": "name",
          "ClaimValue": "Alice Smith"
        },
        {
          "ClaimType": "given_name",
          "ClaimValue": "Alice"
        },
        {
          "ClaimType": "family_name",
          "ClaimValue": "Smith"
        },
        {
          "ClaimType": "middle_name",
          "ClaimValue": "Alice Smith"
        },
        {
          "ClaimType": "nickname",
          "ClaimValue": "alice"
        },
        {
          "ClaimType": "website",
          "ClaimValue": "http://alice.com"
        },
        {
          "ClaimType": "address",
          "ClaimValue": "{ \"street_address\": \"One Hacker Way\", \"locality\": \"Heidelberg\", \"postal_code\": \"69118\", \"country\": \"Germany\" }",
        },
        {
          "ClaimType": "birthdate",
          "ClaimValue": "1970-01-01"
        },
        {
          "ClaimType": "zoneinfo",
          "ClaimValue": "ch"
        },
        {
          "ClaimType": "gender",
          "ClaimValue": "female"
        },
        {
          "ClaimType": "profile",
          "ClaimValue": "http://alice.com/profile"
        },
        {
          "ClaimType": "locale",
          "ClaimValue": "fr"
        },
        {
          "ClaimType": "picture",
          "ClaimValue": "http://alice.com/picture"
        }
      ]
    }
  ]
}

A user with Is4-Writer and Is4-Reader roles is required to use the admin app.

Protected resources (API)

Apis defined in InitialData:Apis configuration section are loaded and stored to the DB.

Default configuration:

"InitialData": {
...
  "Apis": [
    {
      "Name": "theidserveradminapi",
      "DisplayName": "TheIdServer admin API",
      "UserClaims": [
        "name",
        "role"
      ],
      "ApiSecrets": [
        {
          "Type": "SharedSecret",
          "Value": "5b556f7c-b3bc-4b5b-85ab-45eed0cb962d"
        }
      ],
      "Scopes": [
        "theidserveradminapi"
      ]
    }
  ],
}

The api theidserveradminapi is required for the admin app.

ApiScopes

ApiScopes defined in InitialData:ApiScopes configuration section are loaded and stored to the DB.

Default configuration:

"InitialData": {
...
  "ApiScopes": [
    {
      "Name": "theidserveradminapi",
      "DisplayName": "TheIdServer admin API",
      "UserClaims": [
        "name",
        "role"
      ]
    }
  ],
}

The scope theidserveradminapi is required for the admin app.

Clients

Clients defined in InitialData:Clients configuration section are loaded and stored to the DB.

Default configuration:

"InitialData": {
...
  "Clients": [
    {
      "ClientId": "theidserveradmin",
      "ClientName": "TheIdServer admin SPA Client",
      "ClientUri": "https://localhost:5443/",
      "ClientClaimsPrefix": null,
      "AllowedGrantTypes": [ "authorization_code" ],
      "RequirePkce": true,
      "RequireClientSecret": false,
      "BackChannelLogoutSessionRequired": false,
      "FrontChannelLogoutSessionRequired": false,
      "RedirectUris": [
        "http://localhost:5001/authentication/login-callback",
        "https://localhost:5443/authentication/login-callback"
      ],
      "PostLogoutRedirectUris": [
        "http://localhost:5001/authentication/logout-callback",
        "https://localhost:5443/authentication/logout-callback"
      ],
      "AllowedCorsOrigins": [
        "http://localhost:5001",
        "https://localhost:5443"
      ],
      "AllowedScopes": [
        "openid",
        "profile",
        "theidserveradminapi"
      ],
      "AccessTokenType": "Reference"
    },
    {
      "ClientId": "public-server",
      "ClientName": "Public server Credentials Client",
      "ClientClaimsPrefix": null,
      "AllowedGrantTypes": [ "client_credentials" ],
      "ClientSecrets": [
        {
          "Type": "SharedSecret",
          "Value": "84137599-13d6-469c-9376-9e372dd2c1bd"
        }
      ],
      "Claims": [
        {
          "Type": "role",
          "Value": "Is4-Writer"
        },
        {
          "Type": "role",
          "Value": "Is4-Reader"
        }
      ],
      "BackChannelLogoutSessionRequired": false,
      "FrontChannelLogoutSessionRequired": false,
      "AllowedScopes": [
        "openid",
        "profile",
        "theidserveradminapi"
      ],
      "AccessTokenType": "Reference"
    }
  ],
}

The client theidserveradmin is required by the admin app.
The client public-server is required to call web apis and server side prerendering of the admin app.

Configure Signing Key

Keys rotatation (recommanded)

TheIdServer can be configured with a keys rotation mechanism instead of a single key.
Read Keys rotation to know how to configure it.

"IdentityServer": {
  "Key": {
    "Type": "KeysRotation",
    "StorageKind": "EntityFramework"
  }
}

From file

"IdentityServer": {
  "Key": {
    "Type": "File",
    "FilePath": "{path to the .pfx}",
    "Password":  "{.pfx password}"
  }
}

From store

Read Example: Deploy to Azure Websites

Configure the Email service

By default, the server uses SendGrid to send Emails by calling the API at /api/email

"SendGridUser": "your user",
"SendGridKey": "your SendGrid key"

Use your API

If you prefer to use your Email sender, implement a Web API receiving a POST request with the json:

{
  "subject": "Email subject",
  "message": "Email message",
  "addresses": [
    "an-address@aguacongas.con"
  ]
}

And update the EmailApiAuthentication configuration section:

"EmailApiAuthentication": {
  "Authority": "https://localhost:5443",
  "ApiUrl": "https://localhost:5443/api/email",
  "ClientId": "public-server",
  "ClientSecret": "84137599-13d6-469c-9376-9e372dd2c1bd",
  "Scope": "theidserveradminapi",
  "HttpClientName": "email"
}

If you want to use the same authentication configuration and token for both EmailApi and PrivateServer, you can simplify it by sharing the same HttpClientName.

"EmailApiAuthentication": {
  "ApiUrl": "https://localhost:5443/api/email",
  "HttpClientName": "is4"
}

Configure the 2fa authenticator issuer

By default, the issuer for the 2fa authenticator is Aguacongas.TheIdServer.
To update this value, set AuthenticatorIssuer with your issuer.

"AuthenticatorIssuer": "TheIdServer"

Configure the API

Authentication

The ApiAuthentication section defines the authentication configuration for the API.

"ApiAuthentication": {
  "Authority": "https://localhost",
  "RequireHttpsMetadata": false,
  "SupportedTokens": "Both",
  "ApiName": "theidserveradminapi",
  "ApiSecret": "5b556f7c-b3bc-4b5b-85ab-45eed0cb962d",
  "EnableCaching": true,
  "CacheDuration": "0:10:0",
  "LegacyAudienceValidation": true
}

Documentation endpoint

To enable the API documentation, set EnableOpenApiDoc to true.

"EnableOpenApiDoc": true

Use the section SwaggerUiSettings to configure the swagger client authentication.

"SwaggerUiSettings": {
  "Path": "/api/swagger",
  "OAuth2Client": {
    "ClientId": "theidserver-swagger",
    "AppName": "TheIdServer Swagger UI",
    "UsePkceWithAuthorizationCodeGrant": true
  },
  "WithCredentials": true
}

CORS

The section CorsAllowedOrigin defines allowed CORS origins.

"CorsAllowedOrigin": [
  "http://localhost:5001"
]

Configure HTTPS

To disable HTTPS, set DisableHttps to false.

"DisableHttps": true

If you use a self-signed certificate, you can disable strict-SSL by settings DisableStrictSsl to true.

"DisableStrictSsl": true

Configure Forwarded Headers

The section ForwardedHeadersOptions is bound to the class Microsoft.AspNetCore.Builder.ForwardedHeadersOptions.

"ForwardedHeadersOptions": {
  "ForwardedHeaders": "All"
}

Force HTTPS scheme

Some reverses proxies don't' forward headers. You can force HTTP requests schemes to https by settings ForceHttpsScheme.

"ForceHttpsScheme": true

Configure the provider hub

The Aguacongas.AspNetCore.Authentication library dynamically configures external providers.
In a load-balanced configuration, the provider hub informs other running instances that an external provider configuration changes.
The SignalR section defines the configuration for both the SignalR hub and the client.

"SignalR": {
  "HubUrl": "https://theidserverprivate/providerhub",
  "HubOptions": {
    "EnableDetailedErrors": true
  },
  "UseMessagePack": true,
  "RedisConnectionString": "redis:6379",
  "RedisOptions": {
    "Configuration": {
      "ChannelPrefix": "TheIdServer"
    }
  }
}

If needed, the hub can use a Redis backplane. SignalR:RedisConnectionString and SignalR:RedisOptions configures the backplane.
SignalR:RedisOptions is bound to an instance of Microsoft.AspNetCore.SignalR.StackExchangeRedis.RedisOptions at startup.

Configure logs

The Serilog section defines the Serilog configuration.

"Serilog": {
  "LevelSwitches": {
    "$controlSwitch": "Information"
  },
  "MinimumLevel": {
    "ControlledBy": "$controlSwitch"
  },
  "WriteTo": [
    {
      "Name": "Seq",
      "Args": {
        "serverUrl": "http://localhost:5341",
        "controlLevelSwitch": "$controlSwitch",
        "apiKey": "DVYuookX2vOq078fuOyJ"
      }
    },
    {
      "Name": "Console",
      "Args": {
        "outputTemplate": "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}",
        "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Literate, Serilog.Sinks.Console"
      }
    },
    {
      "Name": "Debug",
      "Args": {
        "outputTemplate": "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}"
      }
    }
  ],
  "Enrich": [
    "FromLogContext",
    "WithMachineName",
    "WithThreadId"
  ]
}

For more details, read Serilog.Settings.Configuration.

Configure claims providers

Claims provider provides details on claims proivder configuration.

Configure token cleaner

The token cleaner task removes expired tokens periodically. To configure the interval, use TokenCleanupInterval.

"TokenCleanupInterval": "00:05:00"

To disable the task, use DisableTokenCleanup.

"DisableTokenCleanup":  true

The task is not enabled on proxy server.

Configure Dynamic client registration allowed contacts a host

The server supports OpenID Connect Dynamic Client Registration.

New client registration is allowed to users with the Is4-Writer role by sending the user access token or to contacts defined in DynamicClientRegistrationOptions section.

"DynamicClientRegistrationOptions": {
  "AllowedContacts": [
    {
      "Contact": "certification@oidf.org",
      "AllowedHosts": [
        "www.certification.openid.net"
      ]
    }
  ]
}

It this case, the client registration request must contain the contacts array.

request sample

{
    "client_name": "oidc_cert_client gUPPBlHIEAqNOYR",
    "grant_types": [
        "authorization_code"
    ],
    "response_types": [
        "code"
    ],
    "redirect_uris": [
        "https://www.certification.openid.net/test/a/theidserver/callback"
    ],
    "contacts": [
        "certification@oidf.org"
    ]
}

Configure Jwt request validator

Tokens returned by request_uri parameter are validated using the rules defined in TokenValidationParameters section. By default, the following rules are defined.

"TokenValidationParameters": {
  "ValidateIssuer": false,
  "ValidateAudience": false,
  "ValidateIssuerSigningKey": false,
  "ValidateLifetime": false,
  "RequireAudience": false,
  "RequireExpirationTime": false,
  "RequireSignedTokens": false
}

To enable JWT request uri, set EnableJwtRequestUri to true in IdentityServerOptions:Endpoints

"IdentityServerOptions": {
  "Endpoints": {
    "EnableJwtRequestUri": true
  }
},

Configure WS-Federation endpoint

Read Aguacongas.IdentityServer.WsFederation.Duende

Configure CIBA notification service

Read DUENDE CIBA INTEGRATION/Notification service

Use the client to override the default configuration

The server and the blazor app integrate Aguafrommars/DynamicConfiguration. Most of the configuration can be ovveriden using the blazor app.

Use DynamicConfigurationOptions to define the dynamic configuration provider.

"DynamicConfigurationOptions": {
  "ProviderType": "Aguacongas.DynamicConfiguration.Redis.RedisConfigurationProvider, Aguacongas.DynamicConfiguration.Redis"
}

Use RedisConfigurationOptions section to configure the Redis db.

"RedisConfigurationOptions": {
  "ConnectionString": "localhost",
  "HashKey": "Aguacongas.TheIdServer.Duende",
  "Channel": "Aguacongas.TheIdServer.Duende.Channel"
}

Health checks

The server expose an health checks enpoint you can use for docker on kubernetes at /healthz.

The endpoit return a json reponse depending on the store kind used and redis dependencies :

{
  "status": "Healthy",
  "results": {
    "ConfigurationDbContext": {
      "status": "Healthy"
    },
    "OperationalDbContext": {
      "status": "Healthy"
    },
    "ApplicationDbContext": {
      "status": "Healthy"
    },
    "DynamicConfigurationRedis": {
      "status": "Healthy"
    }
  }
}

Configure OpenTelemetry

Configure OpenTelemetry doc provides details on OpenTelemetry configuration.

Additional resources

Authors: Olivier Lefebvre