默认情况下,数据保护系统使用发现机制来确定应在何处保存加密密钥。 开发人员可以重写默认的发现机制,并手动指定的位置。
警告
如果指定了显式密钥持久性位置,数据保护系统注销 rest 机制,在默认密钥加密,因此不再静态加密密钥。 建议你另外指定用于生产部署的显式密钥加密机制。
若要配置基于文件系统的密钥存储库,请调用PersistKeysToFileSystem配置例程,如下所示。 提供指向存储密钥的存储库的DirectoryInfo :
public void ConfigureServices(IServiceCollection services) { services.AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(@"c:\temp-keys\")); }
DirectoryInfo
可以指向本地计算机上的目录,也可以指向网络共享上的文件夹。 如果指向本地计算机上的目录(并且方案为仅本地计算机上的应用需要使用此存储库的访问权限),请考虑使用WINDOWS DPAPI (在 windows 上)对静态密钥进行加密。 否则,请考虑使用x.509 证书来加密静态密钥。
AspNetCore. DataProtection. AzureStorage package 允许将数据保护密钥存储在 Azure Blob 存储中。 可以在 web 应用的多个实例之间共享密钥。 应用可以跨多个服务器共享身份验证 cookie 或 CSRF 保护。
若要配置 Azure Blob 存储提供程序,请调用PersistKeysToAzureBlobStorage重载之一。
public void ConfigureServices(IServiceCollection services) { services.AddDataProtection() .PersistKeysToAzureBlobStorage(new Uri("<blob URI including SAS token>")); }
如果 web 应用作为 Azure 服务运行,则可以使用microsoft.azure.services.appauthentication自动创建身份验证令牌。
var tokenProvider = new AzureServiceTokenProvider(); var token = await tokenProvider.GetAccessTokenAsync("https://storage.azure.com/"); var credentials = new StorageCredentials(new TokenCredential(token)); var storageAccount = new CloudStorageAccount(credentials, "mystorageaccount", "core.windows.net", useHttps: true); var client = storageAccount.CreateCloudBlobClient(); var container = client.GetContainerReference("my-key-container"); // optional - provision the container automatically await container.CreateIfNotExistsAsync(); services.AddDataProtection() .PersistKeysToAzureBlobStorage(container, "keys.xml");
AspNetCore. DataProtection. StackExchangeRedis package 允许在 Redis 缓存中存储数据保护密钥。 可以在 web 应用的多个实例之间共享密钥。 应用可以跨多个服务器共享身份验证 cookie 或 CSRF 保护。
AspNetCore. DataProtection. Redis package 允许在 Redis 缓存中存储数据保护密钥。 可以在 web 应用的多个实例之间共享密钥。 应用可以跨多个服务器共享身份验证 cookie 或 CSRF 保护。
若要在 Redis 上进行配置,请调用PersistKeysToStackExchangeRedis重载之一:
public void ConfigureServices(IServiceCollection services) { var redis = ConnectionMultiplexer.Connect("<URI>"); services.AddDataProtection() .PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys"); }
若要在 Redis 上进行配置,请调用PersistKeysToRedis重载之一:
public void ConfigureServices(IServiceCollection services) { var redis = ConnectionMultiplexer.Connect("<URI>"); services.AddDataProtection() .PersistKeysToRedis(redis, "DataProtection-Keys"); }
有关详情,请参阅以下主题:
仅适用于 Windows 部署。
有时应用程序可能没有到文件系统的写访问权限。 请考虑一个应用以虚拟服务帐户(例如w3wp.exe的应用程序池标识)运行的方案。 在这些情况下,管理员可以预配的服务帐户标识都可访问的注册表项。 调用PersistKeysToRegistry扩展方法,如下所示。 提供一个RegistryKey ,指向应存储加密密钥的位置:
public void ConfigureServices(IServiceCollection services) { services.AddDataProtection() .PersistKeysToRegistry(Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Sample\keys")); }
重要
建议使用WINDOWS DPAPI来加密静态密钥。
AspNetCore. DataProtection. microsoft.entityframeworkcore包提供了一种机制,用于使用 Entity Framework Core 将数据保护密钥存储到数据库。 必须将 Microsoft.AspNetCore.DataProtection.EntityFrameworkCore
NuGet 包添加到项目文件中,它不是AspNetCore 元包的一部分。
通过此包,可以在 web 应用的多个实例之间共享密钥。
若要配置 EF Core 提供程序,请调用PersistKeysToDbContext<TContext >方法:
public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection"))); // Add a DbContext to store your Database Keys services.AddDbContext<MyKeysContext>(options => options.UseSqlServer( Configuration.GetConnectionString("MyKeysConnection"))); // using Microsoft.AspNetCore.DataProtection; services.AddDataProtection() .PersistKeysToDbContext<MyKeysContext>(); services.AddDefaultIdentity<IdentityUser>() .AddDefaultUI(UIFramework.Bootstrap4) .AddEntityFrameworkStores<ApplicationDbContext>(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
泛型参数 TContext
必须继承自DbContext并实现IDataProtectionKeyContext:
using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using WebApp1.Data; namespace WebApp1 { class MyKeysContext : DbContext, IDataProtectionKeyContext { // A recommended constructor overload when using EF Core // with dependency injection. public MyKeysContext(DbContextOptions<MyKeysContext> options) : base(options) { } // This maps to the table that stores keys. public DbSet<DataProtectionKey> DataProtectionKeys { get; set; } } }
创建 DataProtectionKeys
表。
在 "包管理器控制台" (PMC)窗口中执行以下命令:
Add-Migration AddDataProtectionKeys -Context MyKeysContext Update-Database -Context MyKeysContext
在命令行界面中执行以下命令:
dotnet ef migrations add AddDataProtectionKeys --context MyKeysContext dotnet ef database update --context MyKeysContext
MyKeysContext
是前面的代码示例中定义的 DbContext
。 如果你使用的是其他名称的 DbContext
,请将 DbContext
名称替换为 MyKeysContext
。
DataProtectionKeys
类/实体采用下表所示的结构。
属性/字段 | CLR 类型 | SQL 类型 |
---|---|---|
Id |
int |
int ,PK,not null |
FriendlyName |
string |
nvarchar(MAX) ,null |
Xml |
string |
nvarchar(MAX) ,null |
如果不适合使用机箱内机制,开发人员可以通过提供自定义IXmlRepository来指定其自己的密钥持久性机制。