-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDataProtectionServiceCollectionExtensions.cs
97 lines (78 loc) · 4.05 KB
/
DataProtectionServiceCollectionExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
using System;
using Bet.Extensions.DataProtection.AzureStorage;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Azure.KeyVault;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.DependencyInjection
{
public static class DataProtectionServiceCollectionExtensions
{
public static IServiceCollection AddDataProtectionAzureStorage(
this IServiceCollection services,
IConfiguration configuration,
string sectionName = "AzureDataProtection",
string dataProtectionSectionName = "DataProtectionAzureStorage",
Action<DataProtectionAzureStorageOptions>? setup = null)
{
var enabledDataProtection = configuration.GetValue<bool>(sectionName);
if (enabledDataProtection)
{
services.AddDataProtectionAzureStorage(dataProtectionSectionName, setup);
}
return services;
}
public static IServiceCollection AddDataProtectionAzureStorage(
this IServiceCollection services,
string dataProtectionSectionName = "DataProtectionAzureStorage",
Action<DataProtectionAzureStorageOptions>? setup = null)
{
services.AddDataProtectionOptions(dataProtectionSectionName, setup);
services.ConfigureOptions<KeyManagementOptionsSetup>();
services.AddDataProtection().ProtectKeysWithAzureKeyVault();
return services;
}
public static IDataProtectionBuilder ProtectKeysWithAzureKeyVault(this IDataProtectionBuilder builder)
{
// not the preferred action here
var provider = builder.Services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptions<DataProtectionAzureStorageOptions>>();
#pragma warning disable CA2000 // Dispose objects before losing scope
var kvClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(options.Value.TokenProvider.KeyVaultTokenCallback));
#pragma warning restore CA2000 // Dispose objects before losing scope
builder.ProtectKeysWithAzureKeyVault(kvClient, options.Value.KeyVaultKeyId);
return builder;
}
private static IServiceCollection AddDataProtectionOptions(
this IServiceCollection services,
string dataProtectionSectionName,
Action<DataProtectionAzureStorageOptions>? setup = null)
{
var options = new DataProtectionAzureStorageOptions();
setup?.Invoke(options);
services.AddTransient<IConfigureOptions<DataProtectionAzureStorageOptions>>(sp =>
{
return new ConfigureOptions<DataProtectionAzureStorageOptions>(options =>
{
var configuration = sp.GetRequiredService<IConfiguration>();
configuration.Bind(dataProtectionSectionName, options);
setup?.Invoke(options);
});
});
// configure changeable configurations
services.AddSingleton((Func<IServiceProvider, IOptionsChangeTokenSource<DataProtectionAzureStorageOptions>>)((sp) =>
{
var config = sp.GetRequiredService<IConfiguration>().GetSection(dataProtectionSectionName);
return new ConfigurationChangeTokenSource<DataProtectionAzureStorageOptions>(config);
}));
services.AddSingleton(resolver => resolver.GetRequiredService<IOptions<DataProtectionAzureStorageOptions>>().Value);
services.AddSingleton((Func<IServiceProvider, IConfigureOptions<DataProtectionAzureStorageOptions>>)(sp =>
{
var config = sp.GetRequiredService<IConfiguration>().GetSection(dataProtectionSectionName);
return new ConfigureFromConfigurationOptions<DataProtectionAzureStorageOptions>(config);
}));
services.Configure<DataProtectionAzureStorageOptions>(opt => setup?.Invoke(opt));
return services;
}
}
}