/// <summary> /// Registers a <see cref="IKeyEscrowSink"/> to perform escrow before keys are persisted to storage. /// </summary> /// <typeparam name="TImplementation">The concrete type of the <see cref="IKeyEscrowSink"/> to register.</typeparam> /// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param> /// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns> /// <remarks> /// Registrations are additive. The factory is registered as <see cref="ServiceLifetime.Singleton"/>. /// </remarks> public static IDataProtectionBuilder AddKeyEscrowSink <TImplementation>(this IDataProtectionBuilder builder) where TImplementation : class, IKeyEscrowSink { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } builder.Services.AddSingleton <IConfigureOptions <KeyManagementOptions> >(services => { var implementationInstance = services.GetRequiredService <TImplementation>(); return(new ConfigureOptions <KeyManagementOptions>(options => { options.KeyEscrowSinks.Add(implementationInstance); })); }); return(builder); }
/// <summary> /// Sets the default lifetime of keys created by the data protection system. /// </summary> /// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param> /// <param name="lifetime">The lifetime (time before expiration) for newly-created keys. /// See <see cref="KeyManagementOptions.NewKeyLifetime"/> for more information and /// usage notes.</param> /// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns> public static IDataProtectionBuilder SetDefaultKeyLifetime(this IDataProtectionBuilder builder, TimeSpan lifetime) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (lifetime < TimeSpan.Zero) { throw new ArgumentOutOfRangeException(Resources.FormatLifetimeMustNotBeNegative(nameof(lifetime))); } builder.Services.Configure <KeyManagementOptions>(options => { options.NewKeyLifetime = lifetime; }); return(builder); }
/// <summary> /// Configures keys to be encrypted with Windows DPAPI before being persisted to /// storage. /// </summary> /// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param> /// <param name="protectToLocalMachine">'true' if the key should be decryptable by any /// use on the local machine, 'false' if the key should only be decryptable by the current /// Windows user account.</param> /// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns> /// <remarks> /// This API is only supported on Windows platforms. /// </remarks> public static IDataProtectionBuilder ProtectKeysWithDpapi(this IDataProtectionBuilder builder, bool protectToLocalMachine) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } builder.Services.AddSingleton <IConfigureOptions <KeyManagementOptions> >(services => { var loggerFactory = services.GetService <ILoggerFactory>() ?? NullLoggerFactory.Instance; return(new ConfigureOptions <KeyManagementOptions>(options => { CryptoUtil.AssertPlatformIsWindows(); options.XmlEncryptor = new DpapiXmlEncryptor(protectToLocalMachine, loggerFactory); })); }); return(builder); }
/// <summary> /// Registers a <see cref="IKeyEscrowSink"/> to perform escrow before keys are persisted to storage. /// </summary> /// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param> /// <param name="sink">The instance of the <see cref="IKeyEscrowSink"/> to register.</param> /// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns> /// <remarks> /// Registrations are additive. /// </remarks> public static IDataProtectionBuilder AddKeyEscrowSink(this IDataProtectionBuilder builder, IKeyEscrowSink sink) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (sink == null) { throw new ArgumentNullException(nameof(sink)); } builder.Services.Configure <KeyManagementOptions>(options => { options.KeyEscrowSinks.Add(sink); }); return(builder); }
public static IServiceCollection AddFullDataProtection(this IServiceCollection services, string?appDiscriminator, string?blobConnectionString, string?keyName, Uri?keyIdentifier, string?tenantId, string?clientId, string?clientSecret) { if (string.IsNullOrWhiteSpace(appDiscriminator)) { throw new System.ArgumentException("A value must be provided.", nameof(appDiscriminator)); } if (string.IsNullOrWhiteSpace(blobConnectionString)) { throw new System.ArgumentException("A value must be provided.", nameof(blobConnectionString)); } if (string.IsNullOrWhiteSpace(keyName)) { throw new System.ArgumentException("A value must be provided.", nameof(keyName)); } if (keyIdentifier == null) { throw new System.ArgumentException("A value must be provided.", nameof(keyIdentifier)); } if (string.IsNullOrWhiteSpace(clientId)) { throw new System.ArgumentException("A value must be provided.", nameof(clientId)); } if (string.IsNullOrWhiteSpace(clientSecret)) { throw new System.ArgumentException("A value must be provided.", nameof(clientSecret)); } // See: https://docs.microsoft.com/en-us/rest/api/storageservices/Naming-and-Referencing-Containers--Blobs--and-Metadata#container-names var containerName = $"dataprotection-{appDiscriminator}"; IDataProtectionBuilder dataProtectionBuilder = services .AddDataProtection(o => o.ApplicationDiscriminator = appDiscriminator) .PersistKeysToAzureBlobStorage(blobConnectionString, containerName, keyName) .ProtectKeysWithAzureKeyVault(keyIdentifier, new Azure.Identity.ClientSecretCredential(tenantId, clientId, clientSecret)); return(services); }
/// <summary> /// Configures certificates which can be used to decrypt keys loaded from storage. /// </summary> /// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param> /// <param name="certificates">Certificates that can be used to decrypt key data.</param> /// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns> public static IDataProtectionBuilder UnprotectKeysWithAnyCertificate(this IDataProtectionBuilder builder, params X509Certificate2[] certificates) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } builder.Services.Configure <XmlKeyDecryptionOptions>(o => { if (certificates != null) { foreach (var certificate in certificates) { o.AddKeyDecryptionCertificate(certificate); } } }); return(builder); }
/// <summary> /// Configures the data protection system to persist keys to file storage. /// </summary> /// <param name="builder">The builder instance to modify.</param> /// <param name="storageFactory">The storage factory to use.</param> /// <returns>The value <paramref name="builder"/>.</returns> public static IDataProtectionBuilder PersistKeysToFileStorage(this IDataProtectionBuilder builder, Func <IServiceProvider, IFileStorage> storageFactory) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } builder.Services.AddSingleton <IConfigureOptions <KeyManagementOptions> >(services => { var storage = storageFactory?.Invoke(services); if (storage == null) { throw new ArgumentNullException(nameof(storageFactory)); } var loggerFactory = services.GetService <ILoggerFactory>(); return(new ConfigureOptions <KeyManagementOptions>(options => options.XmlRepository = new FoundatioStorageXmlRepository(storage, loggerFactory))); }); return(builder); }
/// <summary> /// Configures the data protection system to persist keys to the specified database and collection in MongoDB. /// </summary> /// <param name="builder">The builder instance to modify.</param> /// <param name="collection">Collection used to store the key list.</param> /// <returns>A reference to the <see cref="IDataProtectionBuilder"/> after this operation has completed.</returns> public static IDataProtectionBuilder PersistKeysToMongoDb(this IDataProtectionBuilder builder, IMongoCollection <MongoDbXmlKey> collection) { if (builder is null) { throw new ArgumentNullException(nameof(builder)); } if (collection is null) { throw new ArgumentNullException(nameof(collection)); } builder.Services.Configure <KeyManagementOptions>(options => { var mongoDbXmlRepository = new MongoDbXmlRepository(collection); options.XmlRepository = mongoDbXmlRepository; }); return(builder); }
/// <summary> /// Configures the data protection system to encrypt keys using AWS Key Management Service master keys /// </summary> /// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param> /// <param name="config">The configuration object specifying how use KMS keys.</param> /// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns> public static IDataProtectionBuilder ProtectKeysWithAwsKms(this IDataProtectionBuilder builder, KmsXmlEncryptorConfig config) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (config == null) { throw new ArgumentNullException(nameof(config)); } Use(builder.Services, ServiceDescriptor.Singleton <IXmlEncryptor>(services => new KmsXmlEncryptor(services.GetRequiredService <IAmazonKeyManagementService>(), config, services))); // Need to ensure KmsXmlDecryptor can actually be constructed Use(builder.Services, ServiceDescriptor.Singleton(config)); Use(builder.Services, ServiceDescriptor.Singleton <IKmsXmlEncryptorConfig>(config)); Use(builder.Services, ServiceDescriptor.Singleton(services => new KmsXmlDecryptor(services))); Use(builder.Services, ServiceDescriptor.Singleton <IXmlDecryptor>(services => services.GetRequiredService <KmsXmlDecryptor>())); return(builder); }
public static void AddWebAppOptions(this IServiceCollection ext, WebApplicationOptions options = null) { ext = ext ?? throw new ArgumentNullException(nameof(ext)); options = options ?? new WebApplicationOptions(); ext.ConfigureApplicationCookie(opt => { opt.Cookie.Name = options.ApplicationCookieName ?? (options.CookieBaseName != null ? $"{options.CookieBaseName}_app" : opt.Cookie.Name); }); ext.ConfigureExternalCookie(opt => { opt.Cookie.Name = options.ExternalCookieName ?? (options.CookieBaseName != null ? $"{options.CookieBaseName}_ext" : opt.Cookie.Name); }); IDataProtectionBuilder dpBuilder = ext.AddDataProtection() .SetApplicationName(options.DataProtection.ApplicationName) .PersistKeysToFileSystem(new DirectoryInfo(options.DataProtection.KeyRingPath)); if (options.DataProtection.DisableAutomaticKeyGeneration) { dpBuilder.DisableAutomaticKeyGeneration(); } }
protected internal override void AddInternal(IDataProtectionBuilder builder) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } var path = this.Path; if (string.IsNullOrWhiteSpace(path)) { throw new InvalidOperationException("The path is not set."); } if (!System.IO.Path.IsPathRooted(path)) { path = System.IO.Path.Combine(builder.HostEnvironment.ContentRootPath, path); } builder.PersistKeysToFileSystem(new DirectoryInfo(path)); }
/// <summary> /// Configures the data protection system to persist keys to the specified path /// in Azure Blob Storage. /// </summary> /// <param name="builder">The builder instance to modify.</param> /// <param name="blobReference">The <see cref="CloudBlockBlob"/> where the /// key file should be stored.</param> /// <returns>The value <paramref name="builder"/>.</returns> /// <remarks> /// The container referenced by <paramref name="blobReference"/> must already exist. /// </remarks> public static IDataProtectionBuilder PersistKeysToAzureBlobStorage(this IDataProtectionBuilder builder, CloudBlockBlob blobReference) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (blobReference == null) { throw new ArgumentNullException(nameof(blobReference)); } // We're basically just going to make a copy of this blob. // Use (container, blobName) instead of (storageuri, creds) since the container // is tied to an existing service client, which contains user-settable defaults // like retry policy and secondary connection URIs. var container = blobReference.Container; var blobName = blobReference.Name; return(PersistKeystoAzureBlobStorageInternal(builder, () => container.GetBlockBlobReference(blobName))); }
public static IDataProtectionBuilder PersistKeysToMongoDb(this IDataProtectionBuilder builder, Func <IServiceProvider, IMongoDatabase> databaseFactory, string collectionName = DataProtectionKeysCollectionName) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (databaseFactory == null) { throw new ArgumentNullException(nameof(databaseFactory)); } builder.Services.AddSingleton <IConfigureOptions <KeyManagementOptions> >(services => { return(new ConfigureOptions <KeyManagementOptions>(options => { options.XmlRepository = new MongoDbXmlRepository(() => databaseFactory(services), collectionName); })); }); return(builder); }
protected internal override void AddInternal(IDataProtectionBuilder builder) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } builder.Services.AddDbContext <DataProtectionContext, SqlServerDataProtectionContext>(optionsBuilder => optionsBuilder.UseSqlServer( this.GetConnectionString(builder.Configuration), options => { if (this.MigrationsAssembly != null) { options.MigrationsAssembly(this.MigrationsAssembly); } } )); base.AddInternal(builder); }
/// <summary> /// Configures the data protection system to persist keys to a specified S3 bucket. /// </summary> /// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param> /// <param name="s3Client">S3 client configured with appropriate credentials.</param> /// <param name="config">The configuration object specifying how to write to S3.</param> /// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns> public static IDataProtectionBuilder PersistKeysToAwsS3(this IDataProtectionBuilder builder, IAmazonS3 s3Client, S3XmlRepositoryConfig config) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (s3Client == null) { throw new ArgumentNullException(nameof(s3Client)); } if (config == null) { throw new ArgumentNullException(nameof(config)); } Use(builder.Services, ServiceDescriptor.Singleton <IMockingWrapper, MockingWrapper>()); Use(builder.Services, ServiceDescriptor.Singleton <IXmlRepository>(services => new S3XmlRepository(s3Client, config, services))); return(builder); }
/// <summary> /// Configures the data protection system to persist the key-ring as a secret in Azure Key Vault /// </summary> /// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param> /// <param name="keyRingName">The name of the secret that will hold the key-ring</param> /// <param name="vaultUrl">The base URL to your Azure Key Vault</param> /// <param name="clientId">The azure clientId</param> /// <param name="tenantId">The azure tenantId</param> /// <param name="secret">The azure client secret</param> /// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns> public static IDataProtectionBuilder PersistKeysToAzureKeyVault(this IDataProtectionBuilder builder, string keyRingName, string vaultUrl, string clientId, string tenantId, string secret) { if (string.IsNullOrEmpty(keyRingName)) { throw new ArgumentNullException(nameof(keyRingName)); } if (string.IsNullOrEmpty(vaultUrl)) { throw new ArgumentNullException(nameof(vaultUrl)); } if (string.IsNullOrEmpty(clientId)) { throw new ArgumentNullException(nameof(clientId)); } if (string.IsNullOrEmpty(tenantId)) { throw new ArgumentNullException(nameof(tenantId)); } if (string.IsNullOrEmpty(secret)) { throw new ArgumentNullException(nameof(secret)); } builder.Services.AddSingleton <IConfigureOptions <KeyManagementOptions> >(services => { return(new ConfigureOptions <KeyManagementOptions>(options => { var loggerFactory = services.GetService <ILoggerFactory>() ?? NullLoggerFactory.Instance; options.XmlRepository = new AzureKeyVaultKeyRingRepository(keyRingName, vaultUrl, clientId, tenantId, secret, loggerFactory); })); }); return(builder); }
/// <summary> /// Sets up data protection to persist session keys in Redis. /// </summary> /// <param name="builder">The <see cref="IDataProtectionBuilder"/> used to set up data protection options.</param> /// <param name="redisConnectionString">The connection string specifying the Redis instance and database for key storage.</param> /// <returns> /// The <paramref name="builder" /> for continued configuration. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="builder" /> or <paramref name="redisConnectionString" /> is <see langword="null" />. /// </exception> /// <exception cref="System.ArgumentException"> /// Thrown if <paramref name="redisConnectionString" /> is empty. /// </exception> public static IDataProtectionBuilder PersistKeysToRedis(this IDataProtectionBuilder builder, string redisConnectionString) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (redisConnectionString == null) { throw new ArgumentNullException(nameof(redisConnectionString)); } if (redisConnectionString.Length == 0) { throw new ArgumentException("Redis connection string may not be empty.", nameof(redisConnectionString)); } var ips = Dns.GetHostAddressesAsync(redisConnectionString).Result; return(builder.Use(ServiceDescriptor.Singleton <IXmlRepository>(services => new RedisXmlRepository(ips.First().ToString(), services.GetRequiredService <ILogger <RedisXmlRepository> >())))); }
/// <summary> /// Add Keyvault protection /// </summary> /// <param name="builder"></param> /// <param name="configuration"></param> public static IDataProtectionBuilder AddAzureKeyVaultDataProtection( this IDataProtectionBuilder builder, IConfiguration configuration) { var config = new DataProtectionConfig(configuration); if (string.IsNullOrEmpty(config.KeyVaultBaseUrl)) { throw new InvalidConfigurationException( "Keyvault base url is missing in your configuration " + "for dataprotection to be able to store the root key."); } var keyName = config.KeyVaultKeyDataProtection; var keyVault = new KeyVaultClientBootstrap(configuration); if (!TryInititalizeKeyAsync(keyVault.Client, config.KeyVaultBaseUrl, keyName).Result) { throw new UnauthorizedAccessException("Cannot access keyvault"); } var identifier = $"{config.KeyVaultBaseUrl.TrimEnd('/')}/keys/{keyName}"; return(builder.ProtectKeysWithAzureKeyVault(keyVault.Client, identifier)); }
public static IDataProtectionBuilder PersistKeysToAwsS3(this IDataProtectionBuilder builder, IAmazonS3 client, S3XmlRepositoryConfig config) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (client == null) { throw new ArgumentNullException(nameof(client)); } if (config == null) { throw new ArgumentNullException(nameof(config)); } builder.Services.Configure <KeyManagementOptions>(options => { options.XmlRepository = new S3XmlRepository(client, config); }); return(builder); }
public static IDataProtectionBuilder PersistKeys(this IDataProtectionBuilder builder, Func <CacheOptions> configure = null) { var options = (configure != null) ? configure() : new CacheOptions(); if (System.String.IsNullOrWhiteSpace(options?.RedisUrl)) { builder.PersistKeysToFileSystem( new DirectoryInfo(Path.Combine(options.SharedFolder, options.DataProtectionFolder)) ); } else { builder.PersistKeysToStackExchangeRedis( ConnectionMultiplexer.Connect(options.RedisUrl), $"{options.Key}-dpk" ); } return(builder); }
public static IDataProtectionBuilder PersistKeysToRegistry(this IDataProtectionBuilder builder, RegistryKey registryKey) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (registryKey == null) { throw new ArgumentNullException(nameof(registryKey)); } builder.Services.AddSingleton <IConfigureOptions <KeyManagementOptions> >(services => { var loggerFactory = services.GetService <ILoggerFactory>() ?? NullLoggerFactory.Instance; return(new ConfigureOptions <KeyManagementOptions>(options => { options.XmlRepository = new RegistryXmlRepository(registryKey, loggerFactory); })); }); return(builder); }
/// <summary> /// Add blob key storage /// </summary> /// <param name="builder"></param> /// <param name="configuration"></param> public static IDataProtectionBuilder AddAzureBlobKeyStorage( this IDataProtectionBuilder builder, IConfiguration configuration) { var storage = new DataProtectionConfig(configuration); var containerName = storage.BlobStorageContainerDataProtection; var connectionString = storage.GetStorageConnString(); if (string.IsNullOrEmpty(connectionString)) { throw new InvalidConfigurationException( "Storage configuration is missing in your configuration for " + "dataprotection to store all keys across all instances."); } var storageAccount = CloudStorageAccount.Parse(storage.GetStorageConnString()); var relativePath = $"{containerName}/keys.xml"; var uriBuilder = new UriBuilder(storageAccount.BlobEndpoint); uriBuilder.Path = uriBuilder.Path.TrimEnd('/') + "/" + relativePath.TrimStart('/'); var block = new CloudBlockBlob(uriBuilder.Uri, storageAccount.Credentials); Try.Op(() => block.Container.Create()); return(builder.PersistKeysToAzureBlobStorage(block)); }
/// <summary> /// Configures the data protection system to persist keys to an EntityFrameworkCore store /// </summary> /// <param name="builder">The <see cref="IDataProtectionBuilder"/> instance to modify.</param> /// <returns>The value <paramref name="builder"/>.</returns> public static IDataProtectionBuilder PersistKeysToDbContext <TContext>(this IDataProtectionBuilder builder) where TContext : DbContext { builder.Services.AddSingleton <IConfigureOptions <KeyManagementOptions> >(provider => { var loggerFactory = provider.GetService <ILoggerFactory>() ?? NullLoggerFactory.Instance; return(new ConfigureOptions <KeyManagementOptions>(options => { options.XmlRepository = new XmlRepository <TContext>(provider, loggerFactory); })); }); builder.Services.AddSingleton <IXmlRepository, XmlRepository <TContext> >(); builder.Services.AddSingleton <IConfigureOptions <KeyManagementOptions> >(serviceProvider => { return(new ConfigureOptions <KeyManagementOptions>(options => { serviceProvider.RunScopedService <IXmlRepository>(xmlRepository => options.XmlRepository = xmlRepository); })); }); return(builder); }
/// <summary> /// Removes keys from the MongoDB repository after they expire or are revoked. /// </summary> /// <param name="builder">The builder instance to modify.</param> /// <returns>A reference to the <see cref="IDataProtectionBuilder"/> after this operation has completed.</returns> /// <exception cref="InvalidOperationException">PersistKeysToMongoDb must be called before this method.</exception> /// <remarks> /// Cleanup will run after this method is called, and whenever the key manager calls <see cref="Microsoft.AspNetCore.DataProtection.Repositories.IXmlRepository.StoreElement"/>. /// </remarks> /// <remarks> /// If a custom key manager is used, it must be configured before calling this method and keys must have an "id" attribute on the top level element. /// </remarks> public static IDataProtectionBuilder AddKeyCleanup(this IDataProtectionBuilder builder) { if (builder is null) { throw new ArgumentNullException(nameof(builder)); } var keyManager = builder.Services.BuildServiceProvider().GetService <IKeyManager>(); builder.Services.Configure <KeyManagementOptions>(options => { if (options.XmlRepository is MongoDbXmlRepository mongodbXmlRepository) { mongodbXmlRepository.SetKeyManager(keyManager); } else { throw new InvalidOperationException($"{nameof(PersistKeysToMongoDb)} must be called before {nameof(AddKeyCleanup)}."); } }); return(builder); }
/// <summary> /// Registers a <see cref="IKeyEscrowSink"/> to perform escrow before keys are persisted to storage. /// </summary> /// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param> /// <param name="factory">A factory that creates the <see cref="IKeyEscrowSink"/> instance.</param> /// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns> /// <remarks> /// Registrations are additive. The factory is registered as <see cref="ServiceLifetime.Singleton"/>. /// </remarks> public static IDataProtectionBuilder AddKeyEscrowSink(this IDataProtectionBuilder builder, Func <IServiceProvider, IKeyEscrowSink> factory) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (factory == null) { throw new ArgumentNullException(nameof(factory)); } builder.Services.AddSingleton <IConfigureOptions <KeyManagementOptions> >(services => { var instance = factory(services); return(new ConfigureOptions <KeyManagementOptions>(options => { options.KeyEscrowSinks.Add(instance); })); }); return(builder); }
/// <summary> /// Configures keys to be encrypted to a given certificate before being persisted to storage. /// </summary> /// <param name="builder">The <see cref="IDataProtectionBuilder"/>.</param> /// <param name="certificate">The certificate to use when encrypting keys.</param> /// <returns>A reference to the <see cref="IDataProtectionBuilder" /> after this operation has completed.</returns> public static IDataProtectionBuilder ProtectKeysWithCertificate(this IDataProtectionBuilder builder, X509Certificate2 certificate) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (certificate == null) { throw new ArgumentNullException(nameof(certificate)); } builder.Services.AddSingleton <IConfigureOptions <KeyManagementOptions> >(services => { var loggerFactory = services.GetService <ILoggerFactory>() ?? NullLoggerFactory.Instance; return(new ConfigureOptions <KeyManagementOptions>(options => { options.XmlEncryptor = new CertificateXmlEncryptor(certificate, loggerFactory); })); }); return(builder); }
/// <summary> /// Configures the data protection system to persist keys to the specified path /// in Azure Blob Storage. /// </summary> /// <param name="builder">The builder instance to modify.</param> /// <param name="connectionString">A connection string includes the authentication information /// required for your application to access data in an Azure Storage /// account at runtime. /// </param> /// <param name="containerName">The container name to use.</param> /// <param name="blobName">The blob name to use.</param> /// <returns>The value <paramref name="builder"/>.</returns> /// <remarks> /// The container referenced by <paramref name="containerName"/><paramref name="blobName"/> must already exist. /// </remarks> public static IDataProtectionBuilder PersistKeysToAzureBlobStorage(this IDataProtectionBuilder builder, string connectionString, string containerName, string blobName) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (connectionString == null) { throw new ArgumentNullException(nameof(connectionString)); } if (containerName == null) { throw new ArgumentNullException(nameof(containerName)); } if (blobName == null) { throw new ArgumentNullException(nameof(blobName)); } var client = new BlobServiceClient(connectionString).GetBlobContainerClient(containerName).GetBlobClient(blobName); return(PersistKeysToAzureBlobStorage(builder, client)); }
public static IDataProtectionBuilder Use(this IDataProtectionBuilder builder, ServiceDescriptor descriptor) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (descriptor == null) { throw new ArgumentNullException(nameof(descriptor)); } for (int i = builder.Services.Count - 1; i >= 0; i--) { if (builder.Services[i]?.ServiceType == descriptor.ServiceType) { builder.Services.RemoveAt(i); } } builder.Services.Add(descriptor); return(builder); }
public static IDataProtectionBuilder PersistKeysToMongoDb(this IDataProtectionBuilder builder, Func <IServiceProvider, IMongoCollection <mongoDb.DataProtectionKey> > getCollection = null) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (getCollection == null) { getCollection = p => p.GetRequiredService <IMongoDatabase>().GetCollection <mongoDb.DataProtectionKey>(nameof(mongoDb.DataProtectionKey)); } builder.Services.AddSingleton <IConfigureOptions <KeyManagementOptions> >(services => { var loggerFactory = services.GetService <ILoggerFactory>() ?? NullLoggerFactory.Instance; return(new ConfigureOptions <KeyManagementOptions>(options => { options.XmlRepository = new mongoDb.MongoDbXmlRepository <mongoDb.DataProtectionKey>(services, loggerFactory); })); }) .AddTransient(p => new mongoDb.MongoCollectionWrapper <mongoDb.DataProtectionKey>(getCollection(p))); return(builder); }
public static IDataProtectionBuilder ProtectKeysWithDpapiNG(this IDataProtectionBuilder builder, string protectionDescriptorRule, DpapiNGProtectionDescriptorFlags flags) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (protectionDescriptorRule == null) { throw new ArgumentNullException(nameof(protectionDescriptorRule)); } builder.Services.AddSingleton <IConfigureOptions <KeyManagementOptions> >(services => { var loggerFactory = services.GetService <ILoggerFactory>() ?? NullLoggerFactory.Instance; return(new ConfigureOptions <KeyManagementOptions>(options => { CryptoUtil.AssertPlatformIsWindows8OrLater(); options.XmlEncryptor = new DpapiNGXmlEncryptor(protectionDescriptorRule, flags, loggerFactory); })); }); return(builder); }