skoruba / Duende.IdentityServer.Admin

The administration for the Duende IdentityServer and Asp.Net Core Identity ⚑
Apache License 2.0
542 stars 188 forks source link
admin adminui duende duende-identityserver duende-identityserver-admin identityserver identityserver-admin ui

Logo

Skoruba.Duende.IdentityServer.Admin ⚑

The administration for the Duende IdentityServer and Asp.Net Core Identity

Project Status

Build status Build status

The application is written in the Asp.Net Core MVC - using .NET 8.0

Requirements

Installation via dotnet new template

dotnet new install Skoruba.Duende.IdentityServer.Admin.Templates::2.3.0

Create new project:

dotnet new skoruba.duende.isadmin --name MyProject --title MyProject --adminemail "admin@example.com" --adminpassword "Pa$$word123" --adminrole MyRole --adminclientid MyClientId --adminclientsecret MyClientSecret --dockersupport true

Project template options:

--name: [string value] for project name
--adminpassword: [string value] admin password
--adminemail: [string value] admin email
--title: [string value] for title and footer of the administration in UI
--adminrole: [string value] for name of admin role, that is used to authorize the administration
--adminclientid: [string value] for client name, that is used in the Duende IdentityServer configuration for admin client
--adminclientsecret: [string value] for client secret, that is used in the Duende IdentityServer configuration for admin client
--dockersupport: [boolean value] include docker support

How to configure the Administration - Duende IdentityServer and Asp.Net Core Identity

Template uses following list of nuget packages

Running in Visual Studio

Configuration of Administration for Deployment

Administration UI preview

Admin UI - Light mode 🌞

Admin-preview

Admin UI - Dark mode πŸŒ™

Admin-preview

Security token service (STS)

Admin-preview

Forms:

Admin-preview-form

Cloning

git clone https://github.com/skoruba/Duende.IdentityServer.Admin

Running via Docker

Docker setup

DNS

We need some resolving capabilities in order for the project to work. The domain skoruba.local is used here to represent the domain this setup is hosted on. The domain-name needs to be FQDN (fully qualified domain name).

Thus first, we need the domain skoruba.local to resolve to the docker-host machine. If you want this to work on your local machine only, use the first option.

DNS on docker-host machine only

Edit your hosts file:

and add the following entries:

127.0.0.1 skoruba.local sts.skoruba.local admin.skoruba.local admin-api.skoruba.local

This way your host machine resolves skoruba.local and its subdomains to itself.

Certificates

We also need certificates in order to serve on HTTPS. We'll make our own self-signed certificates with mkcert.

If the domain is publicly available through DNS, you can use Let's Encypt. Nginx-proxy has support for that, which is left out in this setup.

MkCert

Create the root certificate

Use mkcert to generate local self-signed certificates.

On windows mkcert -install must be executed under elevated Administrator privileges. Then copy over the CA Root certificate over to the project as we want to mount this in later into the containers without using an environment variable. Use PowerShell to run the commands.

cd shared/nginx/certs
mkcert --install
copy $env:LOCALAPPDATA\mkcert\rootCA-key.pem ./cacerts.pem
copy $env:LOCALAPPDATA\mkcert\rootCA.pem ./cacerts.crt
Create the skoruba.local certificates

Generate a certificate for skoruba.local with wildcards for the subdomains. The name of the certificate files need to match with actual domain-names in order for the nginx-proxy to pick them up correctly. We want both the crt-key and the pfx version.

cd shared/nginx/certs
mkcert -cert-file skoruba.local.crt -key-file skoruba.local.key skoruba.local *.skoruba.local
mkcert -pkcs12 skoruba.local.pfx skoruba.local *.skoruba.local
This docker setup is come from this repository - thanks to bravecobra. 😊

Run docker-compose

docker-compose build
docker-compose up -d

It is also possible to set as startup project the project called docker-compose in Visual Studio.

Docker images

Publish Docker images to Docker hub

Installation of the Client Libraries

cd src/Skoruba.Duende.IdentityServer.Admin
npm install

cd src/Skoruba.Duende.IdentityServer.STS.Identity
npm install

Bundling and Minification

The following Gulp commands are available:

EF Core & Data Access

Run entity framework migrations:

NOTE: Initial migrations are a part of the repository.

Available database providers:

It is possible to switch the database provider via appsettings.json:

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

Connection strings samples for available db providers:

PostgreSQL:

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

MySql:

server=localhost;database=DuendeIdentityServerAdmin;user=root;password=#

We suggest to use seed data:

Authentication and Authorization

Azure Key Vault

"AzureKeyVaultConfiguration": {
    "AzureKeyVaultEndpoint": "",
    "ClientId": "",
    "ClientSecret": "",
    "UseClientCredentials": true
  }

If your application is running in Azure App Service, you can specify AzureKeyVaultEndpoint. For applications which are running outside of Azure environment it is possible to use the client credentials flow - so it is necesarry to go to Azure portal, register new application and connect this application to Azure Key Vault and setup the client secret.

Application Secrets and Database Connection Strings:

"AzureKeyVaultConfiguration": {
    "ReadConfigurationFromKeyVault": true
  }

Dataprotection:

Enable Azure Key Vault for dataprotection with following configuration:

"DataProtectionConfiguration": {
    "ProtectKeysWithAzureKeyVault": false
  }

The you need specify the key identifier in configuration:

"AzureKeyVaultConfiguration": {
    "DataProtectionKeyIdentifier": ""
  }

IdentityServer certificate for signing tokens:

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

Logging

{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Error",
      "Override": {
        "Skoruba": "Information"
      }
    },
    "WriteTo": [
      {
        "Name": "Console"
      },
      {
        "Name": "File",
        "Args": {
          "path": "log.txt",
          "rollingInterval": "Day"
        }
      },
      {
        "Name": "MSSqlServer",
        "Args": {
          "connectionString": "...",
          "tableName": "Log",
          "columnOptionsSection": {
            "addStandardColumns": ["LogEvent"],
            "removeStandardColumns": ["Properties"]
          }
        }
      }
    ]
  }
}

Audit Logging

services.AddAuditLogging(options => { options.Source = auditLoggingConfiguration.Source; })
                .AddDefaultHttpEventData(subjectOptions =>
                    {
                        subjectOptions.SubjectIdentifierClaim = auditLoggingConfiguration.SubjectIdentifierClaim;
                        subjectOptions.SubjectNameClaim = auditLoggingConfiguration.SubjectNameClaim;
                    },
                    actionOptions =>
                    {
                        actionOptions.IncludeFormVariables = auditLoggingConfiguration.IncludeFormVariables;
                    })
                .AddAuditSinks<DatabaseAuditEventLoggerSink<TAuditLog>>();

            // repository for library
            services.AddTransient<IAuditLoggingRepository<TAuditLog>, AuditLoggingRepository<TAuditLoggingDbContext, TAuditLog>>();

            // repository and service for admin
            services.AddTransient<IAuditLogRepository<TAuditLog>, AuditLogRepository<TAuditLoggingDbContext, TAuditLog>>();
            services.AddTransient<IAuditLogService, AuditLogService<TAuditLog>>();

Admin Configuration

Admin and STS can be customized without editing code in appsettings.json under AdminConfiguration section

Themes

UI can be customized using themes integrated from bootswatch.

It's possible to change theme from UI. 🎈

By default, configuration value is null to use default theme. If you want to use a theme, just fill the lowercase theme name as configuration value of Theme key.

You can also use your custom theme by integrating it in your project or hosting css on your place to pass the url in CustomThemeCss key. (Note that custom theme override standard theme)

  "AdminConfiguration": {
    "PageTitle": "Skoruba Duende IdentityServer",
    "HomePageLogoUri": "~/images/skoruba-icon.png",
    "FaviconUri": "~/favicon.ico",
    "Theme": "united",
    "CustomThemeCss": null,
    ...
  },

Audit Logging Configuration

In appsettings.json is following configuration:

"AuditLoggingConfiguration": {
    "Source": "IdentityServer.Admin.Web",
    "SubjectIdentifierClaim": "sub",
    "SubjectNameClaim": "name",
    "IncludeFormVariables": false
  }

The Skoruba.Duende.IdentityServer.Admin.BusinessLogic layer contains folder called Events for audit logging. In each method in Services is called function LogEventAsync like this:

await AuditEventLogger.LogEventAsync(new ClientDeletedEvent(client));

Final audit log is available in the table dbo.AuditLog.

Login Configuration

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

or using Email:

  "LoginConfiguration": {
    "ResolutionPolicy": "Email"
  }

Register Configuration

 "RegisterConfiguration": {
    "Enabled": false
  }

How to configure API & Swagger

"AdminApiConfiguration": {
  "IdentityServerBaseUrl": "https://localhost:44310",
  "OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui",
  "OidcApiName": "skoruba_identity_admin_api"
}

SwaggerUI-preview

How to configure an external provider in STS

"ExternalProvidersConfiguration": {
        "UseGitHubProvider": false,
        "GitHubClientId": "",
        "GitHubClientSecret": "",
        "UseAzureAdProvider": false,
        "AzureAdClientId": "",
        "AzureAdTenantId": "",
        "AzureInstance": "",
        "AzureAdSecret": "",
        "AzureAdCallbackPath": "",
        "AzureDomain": ""
}

List of external providers for ASP.NET Core:

Azure AD

Email service

SendGrid

In STS project - in appsettings.json:

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

SMTP

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

CSP - Content Security Policy

  "CspTrustedDomains": [
    "google.com",
    "mydomain.com"
  ],

Health checks

Localizations - labels, messages

Feel free to send a PR with your translation. :blush:

Tests

Integration tests use StartupTest class which is pre-configured with:

Overview

Solution structure:

The admininistration contains the following sections:

Skoruba.Duende.IdentityServer.Admin App

Duende.IdentityServer

Clients

It is possible to define the configuration according the client type - by default the client types are used:

API Resources

Identity Resources

Asp.Net Core Identity

Users

Roles

Application Diagram

Skoruba.Duende.IdentityServer.Admin Diagram

Roadmap & Vision

1.0.0:

1.1.0

1.2.0

2.0.0

2.1.0

2.2.2

2.3.0

3.0.0

3.1.0

Future:

Licence

This repository is licensed under the terms of the Apache License 2.0.

Duende.IdentityServer License πŸ”‘

Duende.IdentityServer is available under both a FOSS (RPL) and a commercial license.

For the production environment is necessary to get the specific license. For more information about licensing of Duende.IdentityServer - please check this link.

This repository uses the source code from https://github.com/DuendeSoftware/IdentityServer.Quickstart.UI which is under the terms of the following license.

Acknowledgements

This web application is based on these projects:

Thanks to TomΓ‘Ε‘ HΓΌbelbauer for the initial code review.

Thanks to Dominick Baier and Brock Allen - the creators of Duende.IdentityServer.

Contributors

Thanks goes to these wonderful people (emoji key):


Jan Ε koruba

πŸ’» πŸ’¬ πŸ“– πŸ’‘ πŸ€”

TomΓ‘Ε‘ HΓΌbelbauer

πŸ’» πŸ‘€ πŸ“– πŸ€”

MichaΕ‚ DrzaΕ‚

πŸ’» πŸ‘€ πŸ“– πŸ’‘ πŸ€”

cerginio

πŸ’» πŸ› πŸ’‘ πŸ€”

Sven Dummis

πŸ“–

Seaear

πŸ’» 🌍

Rune Antonsen

πŸ›

Sindre NjΓΈsen

πŸ’»

Alevtina Brown

🌍

Brice

πŸ’»

TheEvilPenguin

πŸ’»

Saeed Rahmani

🌍

Andy Yu

🌍

ChrisSzabo

πŸ’»

aiscrim

πŸ’» πŸ’‘ πŸ€”

HrDahl

🌍

Andrew Godfroy

πŸ“–

bravecobra

πŸ’»

Sabit Igde

πŸ’»

Rico Herlt

πŸ’»

b0

πŸ’»

DrQwertySilence

🌍

Carl Quirion

πŸ’»

Aegide

🌍

LobsterBandit

πŸ’»

Mehmet Perk

πŸ’»

tapmui

🌍

Saeed Rahimi

πŸ’»

Joshua Williams

πŸ’»

Shengjie Yan

πŸ’»

Anatoliy

πŸ’»

Nicholas Peterson

πŸ’»

Alec Papierniak

πŸ’»

Carl Reid

πŸ’»

ViRuSTriNiTy

πŸ’»

J. Arturo

πŸ’»

Weihan Li

πŸ’»

Saőa Tančev

πŸ’»

cuibty

πŸ’»

Simo Paasisalo

πŸ’»

klyse

πŸ’»

Martinus Suherman

πŸ’»

Pavel Usachev

πŸ’»

LabTrans - STIGeo

🌍

Valentin LECERF

πŸ’»

Thomas Aunvik

πŸ›

Sebastian Gebhardt

πŸ›

This project follows the all-contributors specification. Contributions of any kind are welcome!

Contact and Suggestion

I am happy to share my attempt of the implementation of the administration for Duende.IdentityServer and ASP.NET Core Identity.

Any feedback is welcome - feel free to create an issue or send me an email - jan@skoruba.com. Thank you :blush:

Support and Donation πŸ•ŠοΈ

If you like my work, you can support me by donation. πŸ‘

Paypal

https://www.paypal.me/skoruba

Patreon

https://www.patreon.com/skoruba