When using the AdminUI nuget package there is a new method of configuring AdminUI, this method allows you to implement your own custom implementation of the IDuendeAdminUISettings
interface. This is in addition to the existing methods of configuring AdminUI.
Logging settings
Logging settings are still obtained from the environment so must be set via an appsettings.json
file, or as envorments variables.
Configuring AdminUI using Settings Model
Instantiate the DuendeAdminUISettings (formerly AdminUISettings)
From AdminUI 9.0 you can instantiate a default implementation of the DuendeAdminUISettings object with its parameterless constructor:
// Program.cs, with Default settings object
var builder = WebApplication.CreateBuilder(args);
DuendeAdminUISettings settings;
// Default
settings = new DuendeAdminUISettings();
Or from AdminUI 6.8 by passing in the IConfiguration object to support taking settings from the dotnet Configuration and also overriding values
// Program.cs, with Default settings object
var builder = WebApplication.CreateBuilder(args);
DuendeAdminUISettings settings;
// Or, Default with IConfiguration
settings = new DuendeAdminUISettings(builder.Configuration);
Implementing your own Settings Model using IDuendeAdminUISettings (formerly IAdminUISettings)
From AdminUI 6.8 you can create your own implementation of the AdminUI setting interface IDuendeAdminUISettings
like so:
public class MyAdminUISettings : IAdminUISettings {
public string DbProvider { get; set; }
...
}
This is how you can set it in Program.cs:
// Program.cs
var builder = WebApplication.CreateBuilder(args);
// Populate settings from anywhere you like
var settings = new MyAdminUISettings();
builder.Services.AddAdminUI(settings);
var app = builder.Build();
app.UseAdminUI();
app.Run();
Backwards compatibility
Also for backwards compatibility, we still support the old version of AddAdminUI
that reads configuration data from key-value pairs using configuration sources such as appsettings.json or environment variables, but this will be deprecated in the future:
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddAdminUI(
options =>
{
// Override default options here
options.IdentityType = IdentityType.DefaultIdentity;
options.MigrationOptions = MigrationOptions.All;
options.DatabaseConnectionFactoryType = DatabaseConnectionFactoryType.Default;
}
);
var app = builder.Build();
app.UseAdminUI();
app.Run();
Configuring KeyVault DataProtection
When using KeyVault data protection with AdminUI NuGet package you only need to set the key identifier in the AdminUI settings as the intention is you would configure KeyVault access yourself making the certificates available to AdminUI throuhgh IConfiguration. A simple way of doing this is provided with the Azure.Extensions.AspNetCore.Configuration.Secrets package which provides an extension method called AddAzureKeyVault
.
This is why the ClientId
, Vault
, and Secret
are not present in the new AdminUI configuration model.
Here is an example of how to implement AddAzureKeyVault()
:
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddAzureKeyVault(new Uri("<Vault URI>"), new DefaultAzureCredential());
builder.Services.AddAdminUI();
var app = builder.Build();
app.UseAdminUI();
app.Run();
Overwriting DataProtection
AdminUI provides settings to configure Data Protection easily. However, there are scenarios where you may require more granular control. For example, suppose you store AdminUI Data Protection keys in a database. In that case, you might want to keep them in a separate table from IdentityServer's keys, using a custom table name, or even place them in a different schema. In such cases, you must override AdminUI's internal call to AddDataProtection()
.
Here is an example demonstrating how to customize the database table schema in Program.cs:
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<AdminUIDataProtectionDbContext>();
builder.Services.AddAdminUI(options =>
options.MigrationOptions = MigrationOptions.None
);
builder.Services.AddDataProtection()
.PersistKeysToDbContext<AdminUIDataProtectionDbContext>()
.ProtectKeysWithCertificate(
new X509Certificate2("certificate.pfx", "password")
);
var app = builder.Build();
app.UseAdminUI();
app.Run();
And the DbContext implementation:
public class AdminUIDataProtectionDbContext : DbContext, IDataProtectionKeyContext
{
public AdminUIDataProtectionDbContext(DbContextOptions<AdminUIDataProtectionDbContext> options) : base(options){}
public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<DataProtectionKey>().ToTable("DataProtectionKey", "myschema");
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("<connection-string>");
}
}
Notice that in the Program.cs file, AddDataProtection()
comes after AddAdminUI()
to overwrite the internal method. Also, remember that you must create your migrations for this new DbContext.