165 lines
6.4 KiB
C#
165 lines
6.4 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using HealthChecks.UI.Client;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using IdentityModel;
|
|
using Duende.IdentityServer;
|
|
using Duende.IdentityServer.Configuration;
|
|
using LiteCharmsSecurity.Admin.EntityFramework.Shared.DbContexts;
|
|
using LiteCharmsSecurity.Admin.EntityFramework.Shared.Entities.Identity;
|
|
using Skoruba.Duende.IdentityServer.Shared.Configuration.Helpers;
|
|
using LiteCharmsSecurity.STS.Identity.Configuration;
|
|
using LiteCharmsSecurity.STS.Identity.Configuration.Constants;
|
|
using LiteCharmsSecurity.STS.Identity.Configuration.Interfaces;
|
|
using LiteCharmsSecurity.STS.Identity.Helpers;
|
|
using LiteCharmsSecurity.STS.Identity.Passkeys;
|
|
using Microsoft.AspNetCore.Identity;
|
|
|
|
namespace LiteCharmsSecurity.STS.Identity
|
|
{
|
|
public class Startup
|
|
{
|
|
public IConfiguration Configuration { get; }
|
|
public IWebHostEnvironment Environment { get; }
|
|
|
|
public Startup(IWebHostEnvironment environment, IConfiguration configuration)
|
|
{
|
|
Configuration = configuration;
|
|
Environment = environment;
|
|
}
|
|
|
|
public void ConfigureServices(IServiceCollection services)
|
|
{
|
|
var rootConfiguration = CreateRootConfiguration();
|
|
services.AddSingleton(rootConfiguration);
|
|
|
|
// Configure ServerSideSessions
|
|
services.Configure<ServerSideSessionsConfiguration>(Configuration.GetSection(ServerSideSessionsConfiguration.SectionName));
|
|
|
|
// Register DbContexts for IdentityServer and Identity
|
|
RegisterDbContexts(services);
|
|
|
|
// Save data protection keys to db, using a common application name shared between Admin and STS
|
|
services.AddDataProtection<IdentityServerDataProtectionDbContext>(Configuration);
|
|
|
|
// Add email senders which is currently setup for SendGrid and SMTP
|
|
services.AddEmailSenders(Configuration);
|
|
|
|
// Add services for authentication, including Identity model and external providers
|
|
RegisterAuthentication(services);
|
|
|
|
// Add HSTS options
|
|
RegisterHstsOptions(services);
|
|
|
|
// Add all dependencies for Asp.Net Core Identity in MVC - these dependencies are injected into generic Controllers
|
|
// Including settings for MVC and Localization
|
|
// If you want to change primary keys or use another db model for Asp.Net Core Identity:
|
|
services.AddMvcWithLocalization<UserIdentity, string>(Configuration);
|
|
services.AddRazorPages();
|
|
|
|
// Add authorization policies for MVC
|
|
RegisterAuthorization(services);
|
|
|
|
// Add IHttpContextAccessor for Passkey TagHelper
|
|
services.AddHttpContextAccessor();
|
|
|
|
// Configure IdentityPasskeyOptions for development
|
|
if (Environment.IsDevelopment())
|
|
{
|
|
services.Configure<IdentityPasskeyOptions>(options =>
|
|
{
|
|
// Allow localhost origins for development
|
|
options.ValidateOrigin = context => ValueTask.FromResult(
|
|
context.Origin.StartsWith("https://localhost") || context.Origin.StartsWith("http://localhost"));
|
|
});
|
|
}
|
|
|
|
services.AddIdSHealthChecks<IdentityServerConfigurationDbContext, IdentityServerPersistedGrantDbContext, AdminIdentityDbContext, IdentityServerDataProtectionDbContext>(Configuration);
|
|
}
|
|
|
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
|
{
|
|
app.UseCookiePolicy();
|
|
|
|
if (env.IsDevelopment())
|
|
{
|
|
app.UseDeveloperExceptionPage();
|
|
}
|
|
else
|
|
{
|
|
app.UseHsts();
|
|
}
|
|
|
|
app.UsePathBase(Configuration.GetValue<string>("BasePath"));
|
|
|
|
|
|
app.UseStaticFiles();
|
|
UseAuthentication(app);
|
|
|
|
// Add custom security headers
|
|
app.UseSecurityHeaders(Configuration);
|
|
|
|
app.UseMvcLocalizationServices();
|
|
|
|
app.UseRouting();
|
|
app.UseAuthorization();
|
|
app.UseEndpoints(endpoint =>
|
|
{
|
|
// Map passkey endpoints for passkey authentication
|
|
endpoint.MapPasskeyEndpoints<UserIdentity>();
|
|
|
|
endpoint.MapDefaultControllerRoute();
|
|
endpoint.MapHealthChecks("/health", new HealthCheckOptions
|
|
{
|
|
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
|
|
});
|
|
});
|
|
}
|
|
|
|
public virtual void RegisterDbContexts(IServiceCollection services)
|
|
{
|
|
services.RegisterDbContexts<AdminIdentityDbContext, IdentityServerConfigurationDbContext, IdentityServerPersistedGrantDbContext, IdentityServerDataProtectionDbContext>(Configuration);
|
|
}
|
|
|
|
public virtual void RegisterAuthentication(IServiceCollection services)
|
|
{
|
|
services.AddAuthenticationServices<AdminIdentityDbContext, UserIdentity, UserIdentityRole>(Configuration);
|
|
services.AddIdentityServer<IdentityServerConfigurationDbContext, IdentityServerPersistedGrantDbContext, UserIdentity>(Configuration);
|
|
}
|
|
|
|
public virtual void RegisterAuthorization(IServiceCollection services)
|
|
{
|
|
var rootConfiguration = CreateRootConfiguration();
|
|
services.AddAuthorizationPolicies(rootConfiguration);
|
|
}
|
|
|
|
public virtual void UseAuthentication(IApplicationBuilder app)
|
|
{
|
|
app.UseIdentityServer();
|
|
}
|
|
|
|
public virtual void RegisterHstsOptions(IServiceCollection services)
|
|
{
|
|
services.AddHsts(options =>
|
|
{
|
|
options.Preload = true;
|
|
options.IncludeSubDomains = true;
|
|
options.MaxAge = TimeSpan.FromDays(365);
|
|
});
|
|
}
|
|
|
|
protected IRootConfiguration CreateRootConfiguration()
|
|
{
|
|
var rootConfiguration = new RootConfiguration();
|
|
Configuration.GetSection(ConfigurationConsts.AdminConfigurationKey).Bind(rootConfiguration.AdminConfiguration);
|
|
Configuration.GetSection(ConfigurationConsts.RegisterConfigurationKey).Bind(rootConfiguration.RegisterConfiguration);
|
|
return rootConfiguration;
|
|
}
|
|
}
|
|
}
|