Skoruba.IdentityServer4.Admin
The administration of the IdentityServer4 and Asp.Net Core Identity
Project Status
The application is written in the Asp.Net Core MVC - using .NET Core 3.1
NOTE: Currently works only with IdentityServer4 version 3 π
Requirements
- Install the latest .NET Core 3.x SDK (using older versions may lead to 502.5 errors when hosted on IIS or application exiting immediately after starting when self-hosted)
Installation via dotnet new template
- Install the dotnet new template:
dotnet new -i Skoruba.IdentityServer4.Admin.Templates::1.0.0-rc2-update1
- Create new project:
dotnet new skoruba.is4admin --name MyProject --title MyProject --adminemail "[email protected]" --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 IdentityServer4 configuration for admin client
--adminclientsecret: [string value] for client secret, that is used in the IdentityServer4 configuration for admin client
--dockersupport: [boolean value] include docker support
How to configure the Administration - IdentityServer4 and Asp.Net Core Identity
Template uses following list of nuget packages
Running in Visual Studio
- Set Startup projects:
- Skoruba.IdentityServer4.Admin
- Skoruba.IdentityServer4.Admin.Api
- Skoruba.IdentityServer4.STS.Identity
Configuration of Administration for Deployment
- Configuration of Admin for deploy on Azure
- Configuration of Admin on Ubuntu with PostgreSQL database
Administration UI preview
-
This administration uses bootstrap 4
-
Admin UI
- Security token service (STS)
- Forms:
Cloning
git clone https://github.com/skoruba/IdentityServer4.Admin
Running via Docker
- It is possible to run Admin UI through the 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:
- On Linux:
\etc\hosts
- On Windows:
C:\Windows\system32\drivers\etc\hosts
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.
cd shared/nginx/certs
mkcert --install
copy $env:LOCALAPPDATA\mkcert\rootCA.pem ./cacerts.pem
copy $env:LOCALAPPDATA\mkcert\rootCA.pem ./cacerts.crt
skoruba.local
certificates
Create the 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
repository - thanks to bravecobra. π
This docker setup is come from thisRun docker-compose
- Project contains the
docker-compose.vs.debug.yml
anddocker-compose.override.yml
to enable debugging with a seeded environment. - The following possibility to get a running seeded and debug-able (in VS) environment:
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
- Docker images will be available also in docker hub
- AdminUI:
skoruba/identityserver4-admin:rc2
- Admin Api:
skoruba/identityserver4-admin-api:rc2
- STS:
skoruba/identityserver4-sts-identity:rc2
- AdminUI:
Publish Docker images to Docker hub
- Check the script in
build/publish-docker-images.ps1
- change the profile name according to your requirements.
Installation of the Client Libraries
cd src/Skoruba.IdentityServer4.Admin
npm install
cd src/Skoruba.IdentityServer4.STS.Identity
npm install
Bundling and Minification
The following Gulp commands are available:
gulp fonts
- copy fonts to thedist
foldergulp styles
- minify CSS, compile SASS to CSSgulp scripts
- bundle and minify JSgulp clean
- remove thedist
foldergulp build
- run thestyles
andscripts
tasks
EF Core & Data Access
-
The solution uses these
DbContexts
:AdminIdentityDbContext
: for Asp.Net Core IdentityAdminLogDbContext
: for loggingIdentityServerConfigurationDbContext
: for IdentityServer configuration storeIdentityServerPersistedGrantDbContext
: for IdentityServer operational storeAuditLoggingDbContext
: for Audit LoggingIdentityServerDataProtectionDbContext
: for dataprotection
Run entity framework migrations:
NOTE: Initial migrations are a part of the repository.
-
It is possible to use powershell script in folder
build/add-migrations.ps1
. -
This script take two arguments:
- --migration (migration name)
- --migrationProviderName (provider type - available choices: All, SqlServer, MySql, PostgreSQL)
-
For example:
.\add-migrations.ps1 -migration DbInit -migrationProviderName SqlServer
Available database providers:
- SqlServer
- MySql
- PostgreSQL
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=IdentityServer4Admin;User Id=sa;Password=#;
MySql:
server=localhost;database=IdentityServer4Admin;user=root;password=#
We suggest to use seed data:
- In
Program.cs
->Main
, uncommentDbMigrationHelpers.EnsureSeedData(host)
or use dotnet CLIdotnet run /seed
or viaSeedConfiguration
inappsettings.json
- The
Clients
andResources
files inidentityserverdata.json
(section called: IdentityServerData) - are the initial data, based on a sample from IdentityServer4 - The
Users
file inidentitydata.json
(section called: IdentityData) contains the default admin username and password for the first login
Authentication and Authorization
- Change the specific URLs and names for the IdentityServer and Authentication settings in
appsettings.json
- In the controllers is used the policy which name is stored in -
AuthorizationConsts.AdministrationPolicy
. In the policy -AuthorizationConsts.AdministrationPolicy
is defined required role stored in -appsettings.json
-AdministrationRole
. - With the default configuration, it is necessary to configure and run instance of IdentityServer4. It is possible to use initial migration for creating the client as it mentioned above
Logging
-
We are using
Serilog
with pre-definded following Sinks - white are available inserilog.json
:- Console
- File
- MSSqlServer
- Seq
{
"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
- This solution uses audit logging via - https://github.com/skoruba/AuditLogging (check this link for more detal about this implementation π)
- In the Admin UI project is following setup:
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>>();
Audit Logging Configuration
In appsettings.json
is following configuration:
"AuditLoggingConfiguration": {
"Source": "IdentityServer.Admin.Web",
"SubjectIdentifierClaim": "sub",
"SubjectNameClaim": "name",
"IncludeFormVariables": false
}
The Skoruba.IdentityServer4.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
- In
Skoruba.IdentityServer4.STS.Identity
- inappsettings.json
is possible to specify which column will be used for login (Username
orEmail
):
"LoginConfiguration": {
"ResolutionPolicy": "Username"
}
or using Email
:
"LoginConfiguration": {
"ResolutionPolicy": "Email"
}
Register Configuration
- In
Skoruba.IdentityServer4.STS.Identity
- inappsettings.json
is possible to disable user registration (default: true
):
"RegisterConfiguration": {
"Enabled": false
}
How to configure API & Swagger
- For development is running on url -
https://localhost:44302
and swagger UI is available on url -https://localhost:44302/swagger
- For swagger UI is configured a client and an API in STS:
"AdminApiConfiguration": {
"IdentityServerBaseUrl": "https://localhost:44310",
"OidcSwaggerUIClientId": "skoruba_identity_admin_api_swaggerui",
"OidcApiName": "skoruba_identity_admin_api"
}
- Swagger UI contains following endpoints:
How to configure an external provider in STS
- In
Skoruba.IdentityServer4.STS.Identity/Helpers/StartupHelpers.cs
- is method calledAddExternalProviders
which contains the example withGitHub
and inappsettings.json
:
"ExternalProvidersConfiguration": {
"UseGitHubProvider": false,
"GitHubClientId": "",
"GitHubClientSecret": ""
}
- It is possible to extend
ExternalProvidersConfiguration
with another configuration properties.
List of external providers for ASP.NET Core:
- https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
- https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/
Azure AD
- Great article how to set up Azure AD:
Email service
- It is possible to set up emails via:
SendGrid
In STS project - in appsettings.json
:
"SendgridConfiguration": {
"ApiKey": "",
"SourceEmail": "",
"SourceName": ""
}
SMTP
"SmtpConfiguration": {
"From": "",
"Host": "",
"Login": "",
"Password": ""
}
Health checks
- AdminUI, AdminUI Api and STS contain endpoint
health
, which check databases and IdentityServer.
Localizations - labels, messages
- The project has following translations:
- English
- Chinese
- Russian
- Persian
- Swedish
- Danish
- Spanish
- French
- Finish
- German
Feel free to send a PR with your translation. π
-
All labels and messages are stored in the resources
.resx
- locatated in/Resources
- Client label descriptions from - http://docs.identityserver.io/en/latest/reference/client.html
- Api Resource label descriptions from - http://docs.identityserver.io/en/latest/reference/api_resource.html
- Identity Resource label descriptions from - http://docs.identityserver.io/en/latest/reference/identity_resource.html
Tests
- The solution contains unit and integration tests.
Integration tests use StartupTest class which is pre-configured with:
DbContext
contains setup for InMemory databaseAuthentication
is setup forCookieAuthentication
- with fake login url for testing purpose onlyAuthenticatedTestRequestMiddleware
- middleware for testing of authentication.
Overview
Solution structure:
-
STS:
Skoruba.IdentityServer4.STS.Identity
- project that contains the instance of IdentityServer4 and combine these samples - Quickstart UI for the IdentityServer4 with Asp.Net Core Identity and EF Core storage and damienbod - IdentityServer4 and Identity template
-
Admin UI Api:
Skoruba.IdentityServer4.Admin.Api
- project with Api for managing data of IdentityServer4 and Asp.Net Core Identity, with swagger support as well
-
Admin UI:
-
Skoruba.IdentityServer4.Admin
- ASP.NET Core MVC application that contains Admin UI -
Skoruba.IdentityServer4.Admin.BusinessLogic
- project that contains Dtos, Repositories, Services and Mappers for the IdentityServer4 -
Skoruba.IdentityServer4.Admin.BusinessLogic.Identity
- project that contains Dtos, Repositories, Services and Mappers for the Asp.Net Core Identity -
Skoruba.IdentityServer4.Admin.BusinessLogic.Shared
- project that contains shared Dtos and ExceptionHandling for the Business Logic layer of the IdentityServer4 and Asp.Net Core Identity -
Skoruba.IdentityServer4.Shared
- Shared common layer for Admin UI, Admin UI Api and STS -
Skoruba.IdentityServer4.Admin.EntityFramework
- EF Core data layer that contains Entities for the IdentityServer4 -
Skoruba.IdentityServer4.Admin.EntityFramework.Identity
- EF Core data layer that contains Repositories for the Asp.Net Core Identity -
Skoruba.IdentityServer4.Admin.EntityFramework.Extensions
- project that contains extensions related to EntityFramework -
Skoruba.IdentityServer4.Admin.EntityFramework.Shared
- project that contains DbContexts for the IdentityServer4, Logging and Asp.Net Core Identity, inluding shared Identity entities -
Skoruba.IdentityServer4.Admin.EntityFramework.SqlServer
- project that contains migrations for SqlServer -
Skoruba.IdentityServer4.Admin.EntityFramework.MySql
- project that contains migrations for MySql -
Skoruba.IdentityServer4.Admin.EntityFramework.PostgreSQL
- project that contains migrations for PostgreSQL
-
-
Tests:
-
Skoruba.IdentityServer4.Admin.IntegrationTests
- xUnit project that contains the integration tests for AdminUI -
Skoruba.IdentityServer4.Admin.Api.IntegrationTests
- xUnit project that contains the integration tests for AdminUI Api -
Skoruba.IdentityServer4.Admin.UnitTests
- xUnit project that contains the unit tests for AdminUI -
Skoruba.IdentityServer4.STS.IntegrationTests
- xUnit project that contains the integration tests for STS
-
The admininistration contains the following sections:
IdentityServer4
Clients
It is possible to define the configuration according the client type - by default the client types are used:
-
Empty
-
Web Application - Server side - Authorization Code Flow with PKCE
-
Single Page Application - Javascript - Authorization Code Flow with PKCE
-
Native Application - Mobile/Desktop - Hybrid flow
-
Machine/Robot - Client Credentials flow
-
TV and Limited-Input Device Application - Device flow
-
Actions: Add, Update, Clone, Remove
-
Entities:
- Client Cors Origins
- Client Grant Types
- Client IdP Restrictions
- Client Post Logout Redirect Uris
- Client Properties
- Client Redirect Uris
- Client Scopes
- Client Secrets
API Resources
- Actions: Add, Update, Remove
- Entities:
- Api Claims
- Api Scopes
- Api Scope Claims
- Api Secrets
- Api Properties
Identity Resources
- Actions: Add, Update, Remove
- Entities:
- Identity Claims
- Identity Properties
Asp.Net Core Identity
Users
- Actions: Add, Update, Delete
- Entities:
- User Roles
- User Logins
- User Claims
Roles
- Actions: Add, Update, Delete
- Entities:
- Role Claims
Application Diagram
Roadmap & Vision
1.0.0:
- Create the Business Logic & EF layers - available as a nuget package
- Create a project template using dotnet CLI -
dotnet new template
- First template: The administration of the IdentityServer4 and Asp.Net Core Identity
- Add logging into
- Database
- File
- Seq
- Add localization for other languages
- English
- Chinese
- Russian
- Persian
- Swedish
- Danish
- Spanish
- French
- Finish
- Manage profile
- Password reset
- Link account to an external provider (example with Github)
- Two-Factor Authentication (2FA)
- User registration
- Email service
- SendGrid
- Add API
- IdentityServer4
- Asp.Net Core Identity
- Add swagger support
- Add audit logs to track changes (#61)
- Docker support (#121)
- Health Checks (Databases and IdentityServer)
- Support for multiple database providers (SqlServer, Mysql, PostgreSQL)
- Simplify Admin Identity middleware (#430)
- Add support for loading signing key from Azure Key Vault (#533)
- Protect keys for dataprotection from Azure Key Vault
2.0.0
- Update to IdentityServer4 version 4 (#633)
3.0.0:
- Create a project template using dotnet CLI -
dotnet new template
- Second template: The administration of the IdentityServer4 (without Asp.Net Core Identity) (#79)
- Connect Admin Api to the Admin UI (#478)
- Add windows authentication (#479)
Future:
- Add UI tests (#97, #116)
- Add more unit and integration tests π
- Extend administration for another protocols
- Create separate UI using
Razor Class Library
(#28, #133)
Licence
This repository is licensed under the terms of the MIT license.
NOTE: This repository uses the source code from https://github.com/IdentityServer/IdentityServer4.Quickstart.UI which is under the terms of the Apache License 2.0.
Acknowledgements
This web application is based on these projects:
- ASP.NET Core
- IdentityServer4.EntityFramework
- ASP.NET Core Identity
- XUnit
- Fluent Assertions
- Bogus
- AutoMapper
- Serilog
Thanks to TomΓ‘Ε‘ HΓΌbelbauer for the initial code review.
Thanks to Dominick Baier and Brock Allen - the creators of IdentityServer4.
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 π» |
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 IdentityServer4 and ASP.NET Core Identity.
Any feedback is welcome - feel free to create an issue or send me an email - [email protected]. Thank you π
Support and Donation ποΈ
If you like my work, you can support me by donation. π