Skip to content

Commit 5c0b9d8

Browse files
feat: Add data protection key storage
1 parent 3de4fe2 commit 5c0b9d8

9 files changed

Lines changed: 410 additions & 26 deletions

.github/workflows/Build-Test-And-Deploy.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ jobs:
169169
AZURE_CLIENT_ID=$AZURECLIENTID HCaptcha__SiteKey=secretref:captcha-sitekey HCaptcha__SecretKey=secretref:captcha-secretkey APPLICATIONINSIGHTS_CONNECTION_STRING=secretref:appinsights-connectionstring \
170170
AIOptions__Endpoint=secretref:ai-endpoint AIOptions__ApiKey=secretref:ai-apikey AIOptions__VectorGenerationDeploymentName=secretref:ai-vectordeployment AIOptions__ChatDeploymentName=secretref:ai-chatdeployment \
171171
AIOptions__SystemPrompt=secretref:ai-systemprompt ConnectionStrings__PostgresVectorStore=secretref:postgres-vectorstore-connectionstring \
172-
TryDotNet__Origin=$TRYDOTNET_ORIGIN
172+
TryDotNet__Origin=$TRYDOTNET_ORIGIN DataProtection__AzureKeyVaultKeyUri=$KEYVAULTURI/keys/dataprotection
173173
174174
- name: Logout of Azure CLI
175175
if: always()
@@ -266,7 +266,7 @@ jobs:
266266
AZURE_CLIENT_ID=$AZURECLIENTID HCaptcha__SiteKey=secretref:captcha-sitekey HCaptcha__SecretKey=secretref:captcha-secretkey APPLICATIONINSIGHTS_CONNECTION_STRING=secretref:appinsights-connectionstring \
267267
AIOptions__Endpoint=secretref:ai-endpoint AIOptions__ApiKey=secretref:ai-apikey AIOptions__VectorGenerationDeploymentName=secretref:ai-vectordeployment AIOptions__ChatDeploymentName=secretref:ai-chatdeployment \
268268
AIOptions__SystemPrompt=secretref:ai-systemprompt ConnectionStrings__PostgresVectorStore=secretref:postgres-vectorstore-connectionstring \
269-
TryDotNet__Origin=$TRYDOTNET_ORIGIN
269+
TryDotNet__Origin=$TRYDOTNET_ORIGIN DataProtection__AzureKeyVaultKeyUri=$KEYVAULTURI/keys/dataprotection
270270
271271
272272
- name: Logout of Azure CLI

Directory.Packages.props

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
44
<CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled>
55
<ToolingPackagesVersion>1.1.1.18932</ToolingPackagesVersion>
6-
<AccessToNugetFeed>false</AccessToNugetFeed>
6+
<AccessToNugetFeed Condition="'$(AccessToNugetFeed)' == ''">false</AccessToNugetFeed>
77
<RestoreSources>
88
https://api.nuget.org/v3/index.json;
99
</RestoreSources>
@@ -19,6 +19,7 @@
1919
<PackageVersion Include="ContentFeedNuget" Version="$(ToolingPackagesVersion)" />
2020
</ItemGroup>
2121
<ItemGroup>
22+
<PackageVersion Include="Azure.Extensions.AspNetCore.DataProtection.Keys" Version="1.6.1" />
2223
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="10.0.6" />
2324
<PackageVersion Include="AspNet.Security.OAuth.GitHub" Version="10.0.0" />
2425
<PackageVersion Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.5.0" />
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
using EssentialCSharp.Web.Areas.Identity.Data;
2+
using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
23
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
34
using Microsoft.EntityFrameworkCore;
45

56
namespace EssentialCSharp.Web.Data;
67

7-
public class EssentialCSharpWebContext(DbContextOptions options) : IdentityDbContext<EssentialCSharpWebUser>(options)
8+
public class EssentialCSharpWebContext(DbContextOptions<EssentialCSharpWebContext> options)
9+
: IdentityDbContext<EssentialCSharpWebUser>(options), IDataProtectionKeyContext
810
{
11+
public DbSet<DataProtectionKey> DataProtectionKeys { get; set; } = null!;
12+
913
protected override void OnModelCreating(ModelBuilder builder)
1014
{
1115
base.OnModelCreating(builder);
12-
// Customize the ASP.NET Identity model and override the defaults if needed.
13-
// For example, you can rename the ASP.NET Identity table names and more.
14-
// Add your customizations after calling base.OnModelCreating(builder);
1516
}
1617
}

EssentialCSharp.Web/DatabaseMigrationService.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,20 @@
33

44
namespace EssentialCSharp.Web;
55

6-
public class DatabaseMigrationService(IServiceScopeFactory services) : BackgroundService
6+
/// <summary>
7+
/// Runs EF Core migrations synchronously in <see cref="StartAsync"/> so the schema
8+
/// is fully applied before the HTTP server begins accepting traffic. This prevents
9+
/// race conditions where a request touches the DataProtectionKeys (or Identity) tables
10+
/// before the migration that creates them has run.
11+
/// </summary>
12+
public class DatabaseMigrationService(IServiceScopeFactory services) : IHostedService
713
{
8-
public IServiceScopeFactory Services { get; } = services;
9-
10-
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
14+
public async Task StartAsync(CancellationToken cancellationToken)
1115
{
12-
using IServiceScope scope = Services.CreateScope();
16+
using IServiceScope scope = services.CreateScope();
1317
EssentialCSharpWebContext context = scope.ServiceProvider.GetRequiredService<EssentialCSharpWebContext>();
14-
await context.Database.MigrateAsync(stoppingToken);
18+
await context.Database.MigrateAsync(cancellationToken);
1519
}
20+
21+
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
1622
}

EssentialCSharp.Web/EssentialCSharp.Web.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
<ItemGroup>
3131
<PackageReference Include="AspNet.Security.OAuth.GitHub" />
32+
<PackageReference Include="Azure.Extensions.AspNetCore.DataProtection.Keys" />
33+
<PackageReference Include="Azure.Identity" />
3234
<PackageReference Include="Azure.Monitor.OpenTelemetry.AspNetCore" />
3335
<PackageReference Include="EssentialCSharp.Shared.Models" />
3436
<PackageReference Include="HtmlAgilityPack" />
@@ -38,6 +40,7 @@
3840
<PackageReference Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" />
3941
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
4042
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" />
43+
<PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" />
4144
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" />
4245
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
4346
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools">

0 commit comments

Comments
 (0)