/// <summary> /// Reads the data protection options directly from configuration. /// </summary> /// <param name="options">Options for configuring ASP.NET Core DataProtection API using Azure Blob Storage infrastructure.</param> /// <param name="section">The section to use in search for settings regarding data protection. Default section used is <see cref="LocalDataProtectionOptions.Name"/>.</param> public static AzureDataProtectionOptions FromConfiguration(this AzureDataProtectionOptions options, string section = null) { var serviceProvider = options.Services.BuildServiceProvider(); var configuration = serviceProvider.GetRequiredService <IConfiguration>(); configuration.Bind(section ?? AzureDataProtectionOptions.Name, options); return(options); }
/// <summary> /// Configures the Data Protection API for the application by using Azure Storage. /// </summary> /// <param name="services">Specifies the contract for a collection of service descriptors.</param> /// <param name="configure">Configures the available options. Null to use defaults.</param> public static IServiceCollection AddDataProtectionAzure(this IServiceCollection services, Action <AzureDataProtectionOptions> configure = null) { services.TryAddSingleton(typeof(IDataProtectionEncryptor <>), typeof(DataProtectionEncryptor <>)); var serviceProvider = services.BuildServiceProvider(); var hostingEnvironment = serviceProvider.GetRequiredService <IWebHostEnvironment>(); var environmentName = Regex.Replace(hostingEnvironment.EnvironmentName ?? "Development", @"\s+", "-").ToLowerInvariant(); const int defaultKeyLifetime = 90; var options = new AzureDataProtectionOptions { StorageConnectionString = serviceProvider.GetRequiredService <IConfiguration>().GetConnectionString("StorageConnection"), ContainerName = environmentName, ApplicationName = hostingEnvironment.ApplicationName, KeyLifetime = defaultKeyLifetime }; options.Services = services; configure?.Invoke(options); options.Services = null; if (options.KeyLifetime <= 0) { options.KeyLifetime = defaultKeyLifetime; } var storageAccount = CloudStorageAccount.Parse(options.StorageConnectionString); var blobClient = storageAccount.CreateCloudBlobClient(); var container = blobClient.GetContainerReference(options.ContainerName); container.CreateIfNotExistsAsync().Wait(); // Enables data protection services to the specified IServiceCollection. var dataProtectionBuilder = services.AddDataProtection() // Configures the data protection system to use the specified cryptographic algorithms by default when generating protected payloads. // The algorithms selected below are the default and they are added just for completeness. .UseCryptographicAlgorithms(new AuthenticatedEncryptorConfiguration { EncryptionAlgorithm = EncryptionAlgorithm.AES_256_GCM, ValidationAlgorithm = ValidationAlgorithm.HMACSHA512 }) .PersistKeysToAzureBlobStorage(container, "Keys") // Configure the system to use a key lifetime. Default is 90 days. .SetDefaultKeyLifetime(TimeSpan.FromDays(options.KeyLifetime)) // This prevents the apps from understanding each other's protected payloads (e.x Azure slots). To share protected payloads between two apps, // use SetApplicationName with the same value for each app. .SetApplicationName(options.ApplicationName); if (options.DisableAutomaticKeyGeneration) { // Configure the system not to automatically roll keys (create new keys) as they approach expiration. dataProtectionBuilder.DisableAutomaticKeyGeneration(); } return(services); }