diff --git a/samples/AzureBlob/AzureBlob.csproj b/samples/AzureBlob/AzureBlob.csproj index 9d688160..899b2542 100644 --- a/samples/AzureBlob/AzureBlob.csproj +++ b/samples/AzureBlob/AzureBlob.csproj @@ -1,9 +1,10 @@ - + netcoreapp2.0 + exe diff --git a/samples/AzureBlob/Program.cs b/samples/AzureBlob/Program.cs index f0aa1efe..cce86046 100644 --- a/samples/AzureBlob/Program.cs +++ b/samples/AzureBlob/Program.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.WindowsAzure.Storage; +using LogLevel = Microsoft.Extensions.Logging.LogLevel; namespace AzureBlob { @@ -24,21 +25,19 @@ public static void Main(string[] args) container.CreateIfNotExistsAsync().GetAwaiter().GetResult(); // Configure - - var serviceCollection = new ServiceCollection(); - serviceCollection.AddLogging(); - serviceCollection.AddDataProtection() - .PersistKeysToAzureBlobStorage(container, "keys.xml"); - - var services = serviceCollection.BuildServiceProvider(); - var loggerFactory = services.GetService(); - loggerFactory.AddConsole(); - - // Run a sample payload - - var protector = services.GetDataProtector("sample-purpose"); - var protectedData = protector.Protect("Hello world!"); - Console.WriteLine(protectedData); + using (var services = new ServiceCollection() + .AddLogging(o => o.AddConsole().SetMinimumLevel(LogLevel.Debug)) + .AddDataProtection() + .PersistKeysToAzureBlobStorage(container, "keys.xml") + .Services + .BuildServiceProvider()) + { + // Run a sample payload + + var protector = services.GetDataProtector("sample-purpose"); + var protectedData = protector.Protect("Hello world!"); + Console.WriteLine(protectedData); + } } } } diff --git a/samples/AzureBlob/Properties/launchSettings.json b/samples/AzureBlob/Properties/launchSettings.json deleted file mode 100644 index ae9a5dab..00000000 --- a/samples/AzureBlob/Properties/launchSettings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:2041/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "AzureBlob": { - "commandName": "Project" - } - } -} \ No newline at end of file diff --git a/samples/CustomEncryptorSample/CustomEncryptorSample.csproj b/samples/CustomEncryptorSample/CustomEncryptorSample.csproj index ca8401e3..ddd92112 100644 --- a/samples/CustomEncryptorSample/CustomEncryptorSample.csproj +++ b/samples/CustomEncryptorSample/CustomEncryptorSample.csproj @@ -1,9 +1,10 @@ - + net461;netcoreapp2.0 + exe diff --git a/samples/CustomEncryptorSample/Program.cs b/samples/CustomEncryptorSample/Program.cs index 89e0f828..9079aeee 100644 --- a/samples/CustomEncryptorSample/Program.cs +++ b/samples/CustomEncryptorSample/Program.cs @@ -14,25 +14,23 @@ public class Program public static void Main(string[] args) { var keysFolder = Path.Combine(Directory.GetCurrentDirectory(), "temp-keys"); - var serviceCollection = new ServiceCollection(); - serviceCollection.AddLogging(); - serviceCollection.AddDataProtection() + using (var services = new ServiceCollection() + .AddLogging(o => o.AddConsole().SetMinimumLevel(LogLevel.Debug)) + .AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(keysFolder)) - .UseXmlEncryptor(s => new CustomXmlEncryptor(s)); + .UseXmlEncryptor(s => new CustomXmlEncryptor(s)) + .Services.BuildServiceProvider()) + { + var protector = services.GetDataProtector("SamplePurpose"); - var services = serviceCollection.BuildServiceProvider(); - var loggerFactory = services.GetRequiredService(); - loggerFactory.AddConsole(); + // protect the payload + var protectedPayload = protector.Protect("Hello World!"); + Console.WriteLine($"Protect returned: {protectedPayload}"); - var protector = services.GetDataProtector("SamplePurpose"); - - // protect the payload - var protectedPayload = protector.Protect("Hello World!"); - Console.WriteLine($"Protect returned: {protectedPayload}"); - - // unprotect the payload - var unprotectedPayload = protector.Unprotect(protectedPayload); - Console.WriteLine($"Unprotect returned: {unprotectedPayload}"); + // unprotect the payload + var unprotectedPayload = protector.Unprotect(protectedPayload); + Console.WriteLine($"Unprotect returned: {unprotectedPayload}"); + } } } } diff --git a/samples/CustomEncryptorSample/Properties/launchSettings.json b/samples/CustomEncryptorSample/Properties/launchSettings.json deleted file mode 100644 index c24bc967..00000000 --- a/samples/CustomEncryptorSample/Properties/launchSettings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:1398/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "CustomEncryptorSample": { - "commandName": "Project" - } - } -} \ No newline at end of file diff --git a/samples/KeyManagementSample/KeyManagementSample.csproj b/samples/KeyManagementSample/KeyManagementSample.csproj index b15e9017..34b42ebd 100644 --- a/samples/KeyManagementSample/KeyManagementSample.csproj +++ b/samples/KeyManagementSample/KeyManagementSample.csproj @@ -1,9 +1,10 @@ - + net461;netcoreapp2.0 + exe diff --git a/samples/KeyManagementSample/Program.cs b/samples/KeyManagementSample/Program.cs index 3feefebc..be128aa1 100644 --- a/samples/KeyManagementSample/Program.cs +++ b/samples/KeyManagementSample/Program.cs @@ -16,7 +16,8 @@ public static void Main(string[] args) { var keysFolder = Path.Combine(Directory.GetCurrentDirectory(), "temp-keys"); var serviceCollection = new ServiceCollection(); - var builder = serviceCollection.AddDataProtection() + var builder = serviceCollection + .AddDataProtection() // point at a specific folder and use DPAPI to encrypt keys .PersistKeysToFileSystem(new DirectoryInfo(keysFolder)); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -24,40 +25,41 @@ public static void Main(string[] args) builder.ProtectKeysWithDpapi(); } - var services = serviceCollection.BuildServiceProvider(); + using (var services = serviceCollection.BuildServiceProvider()) + { + // perform a protect operation to force the system to put at least + // one key in the key ring + services.GetDataProtector("Sample.KeyManager.v1").Protect("payload"); + Console.WriteLine("Performed a protect operation."); - // perform a protect operation to force the system to put at least - // one key in the key ring - services.GetDataProtector("Sample.KeyManager.v1").Protect("payload"); - Console.WriteLine("Performed a protect operation."); + // get a reference to the key manager + var keyManager = services.GetService(); - // get a reference to the key manager - var keyManager = services.GetService(); + // list all keys in the key ring + var allKeys = keyManager.GetAllKeys(); + Console.WriteLine($"The key ring contains {allKeys.Count} key(s)."); + foreach (var key in allKeys) + { + Console.WriteLine($"Key {key.KeyId:B}: Created = {key.CreationDate:u}, IsRevoked = {key.IsRevoked}"); + } - // list all keys in the key ring - var allKeys = keyManager.GetAllKeys(); - Console.WriteLine($"The key ring contains {allKeys.Count} key(s)."); - foreach (var key in allKeys) - { - Console.WriteLine($"Key {key.KeyId:B}: Created = {key.CreationDate:u}, IsRevoked = {key.IsRevoked}"); - } + // revoke all keys in the key ring + keyManager.RevokeAllKeys(DateTimeOffset.Now, reason: "Revocation reason here."); + Console.WriteLine("Revoked all existing keys."); - // revoke all keys in the key ring - keyManager.RevokeAllKeys(DateTimeOffset.Now, reason: "Revocation reason here."); - Console.WriteLine("Revoked all existing keys."); + // add a new key to the key ring with immediate activation and a 1-month expiration + keyManager.CreateNewKey( + activationDate: DateTimeOffset.Now, + expirationDate: DateTimeOffset.Now.AddMonths(1)); + Console.WriteLine("Added a new key."); - // add a new key to the key ring with immediate activation and a 1-month expiration - keyManager.CreateNewKey( - activationDate: DateTimeOffset.Now, - expirationDate: DateTimeOffset.Now.AddMonths(1)); - Console.WriteLine("Added a new key."); - - // list all keys in the key ring - allKeys = keyManager.GetAllKeys(); - Console.WriteLine($"The key ring contains {allKeys.Count} key(s)."); - foreach (var key in allKeys) - { - Console.WriteLine($"Key {key.KeyId:B}: Created = {key.CreationDate:u}, IsRevoked = {key.IsRevoked}"); + // list all keys in the key ring + allKeys = keyManager.GetAllKeys(); + Console.WriteLine($"The key ring contains {allKeys.Count} key(s)."); + foreach (var key in allKeys) + { + Console.WriteLine($"Key {key.KeyId:B}: Created = {key.CreationDate:u}, IsRevoked = {key.IsRevoked}"); + } } } } diff --git a/samples/KeyManagementSample/Properties/launchSettings.json b/samples/KeyManagementSample/Properties/launchSettings.json deleted file mode 100644 index 9f2e8074..00000000 --- a/samples/KeyManagementSample/Properties/launchSettings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:1396/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "KeyManagementSample": { - "commandName": "Project" - } - } -} \ No newline at end of file diff --git a/samples/NonDISample/Program.cs b/samples/NonDISample/Program.cs index f9ccd926..c166f632 100644 --- a/samples/NonDISample/Program.cs +++ b/samples/NonDISample/Program.cs @@ -5,7 +5,6 @@ using System.IO; using System.Runtime.InteropServices; using Microsoft.AspNetCore.DataProtection; -using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; namespace NonDISample { diff --git a/samples/Redis/Program.cs b/samples/Redis/Program.cs index 6731c105..f8f213cf 100644 --- a/samples/Redis/Program.cs +++ b/samples/Redis/Program.cs @@ -17,19 +17,18 @@ public static void Main(string[] args) var redis = ConnectionMultiplexer.Connect("localhost:6379"); // Configure - var serviceCollection = new ServiceCollection(); - serviceCollection.AddLogging(); - serviceCollection.AddDataProtection() - .PersistKeysToRedis(redis, "DataProtection-Keys"); - - var services = serviceCollection.BuildServiceProvider(); - var loggerFactory = services.GetService(); - loggerFactory.AddConsole(); - - // Run a sample payload - var protector = services.GetDataProtector("sample-purpose"); - var protectedData = protector.Protect("Hello world!"); - Console.WriteLine(protectedData); + using (var services = new ServiceCollection() + .AddLogging(o => o.AddConsole().SetMinimumLevel(LogLevel.Debug)) + .AddDataProtection() + .PersistKeysToRedis(redis, "DataProtection-Keys") + .Services + .BuildServiceProvider()) + { + // Run a sample payload + var protector = services.GetDataProtector("sample-purpose"); + var protectedData = protector.Protect("Hello world!"); + Console.WriteLine(protectedData); + } } } } diff --git a/samples/Redis/Properties/launchSettings.json b/samples/Redis/Properties/launchSettings.json deleted file mode 100644 index 4f4c7679..00000000 --- a/samples/Redis/Properties/launchSettings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:2042/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "Redis": { - "commandName": "Project" - } - } -} \ No newline at end of file diff --git a/samples/Redis/Redis.csproj b/samples/Redis/Redis.csproj index 37aecfb6..7040d86a 100644 --- a/samples/Redis/Redis.csproj +++ b/samples/Redis/Redis.csproj @@ -1,9 +1,10 @@ - + net461;netcoreapp2.0 + exe diff --git a/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorConfiguration.cs b/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorConfiguration.cs index c3972e4e..606d7484 100644 --- a/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorConfiguration.cs +++ b/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/AuthenticatedEncryptorConfiguration.cs @@ -4,6 +4,7 @@ using System; using System.Security.Cryptography; using Microsoft.AspNetCore.Cryptography; +using Microsoft.Extensions.Logging.Abstractions; namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel { @@ -42,7 +43,7 @@ IAuthenticatedEncryptorDescriptor IInternalAlgorithmConfiguration.CreateDescript void IInternalAlgorithmConfiguration.Validate() { - var factory = new AuthenticatedEncryptorFactory(DataProtectionProviderFactory.GetDefaultLoggerFactory()); + var factory = new AuthenticatedEncryptorFactory(NullLoggerFactory.Instance); // Run a sample payload through an encrypt -> decrypt operation to make sure data round-trips properly. var encryptor = factory.CreateAuthenticatedEncryptorInstance(Secret.Random(512 / 8), this); try diff --git a/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorConfiguration.cs b/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorConfiguration.cs index 4b741775..1c23957d 100644 --- a/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorConfiguration.cs +++ b/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngCbcAuthenticatedEncryptorConfiguration.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNetCore.Cryptography; +using Microsoft.Extensions.Logging.Abstractions; namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel { @@ -88,7 +89,7 @@ IAuthenticatedEncryptorDescriptor IInternalAlgorithmConfiguration.CreateDescript /// void IInternalAlgorithmConfiguration.Validate() { - var factory = new CngCbcAuthenticatedEncryptorFactory(DataProtectionProviderFactory.GetDefaultLoggerFactory()); + var factory = new CngCbcAuthenticatedEncryptorFactory(NullLoggerFactory.Instance); // Run a sample payload through an encrypt -> decrypt operation to make sure data round-trips properly. using (var encryptor = factory.CreateAuthenticatedEncryptorInstance(Secret.Random(512 / 8), this)) { diff --git a/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorConfiguration.cs b/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorConfiguration.cs index 9cf6e951..d9c1f847 100644 --- a/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorConfiguration.cs +++ b/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/CngGcmAuthenticatedEncryptorConfiguration.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNetCore.Cryptography; +using Microsoft.Extensions.Logging.Abstractions; namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel { @@ -64,7 +65,7 @@ IAuthenticatedEncryptorDescriptor IInternalAlgorithmConfiguration.CreateDescript /// void IInternalAlgorithmConfiguration.Validate() { - var factory = new CngGcmAuthenticatedEncryptorFactory(DataProtectionProviderFactory.GetDefaultLoggerFactory()); + var factory = new CngGcmAuthenticatedEncryptorFactory(NullLoggerFactory.Instance); // Run a sample payload through an encrypt -> decrypt operation to make sure data round-trips properly. using (var encryptor = factory.CreateAuthenticatedEncryptorInstance(Secret.Random(512 / 8), this)) { diff --git a/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorConfiguration.cs b/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorConfiguration.cs index b437d59b..dad6cd9d 100644 --- a/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorConfiguration.cs +++ b/src/Microsoft.AspNetCore.DataProtection/AuthenticatedEncryption/ConfigurationModel/ManagedAuthenticatedEncryptorConfiguration.cs @@ -3,6 +3,7 @@ using System; using System.Security.Cryptography; +using Microsoft.Extensions.Logging.Abstractions; namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel { @@ -66,7 +67,7 @@ IAuthenticatedEncryptorDescriptor IInternalAlgorithmConfiguration.CreateDescript /// void IInternalAlgorithmConfiguration.Validate() { - var factory = new ManagedAuthenticatedEncryptorFactory(DataProtectionProviderFactory.GetDefaultLoggerFactory()); + var factory = new ManagedAuthenticatedEncryptorFactory(NullLoggerFactory.Instance); // Run a sample payload through an encrypt -> decrypt operation to make sure data round-trips properly. using (var encryptor = factory.CreateAuthenticatedEncryptorInstance(Secret.Random(512 / 8), this)) { diff --git a/src/Microsoft.AspNetCore.DataProtection/DataProtectionBuilderExtensions.cs b/src/Microsoft.AspNetCore.DataProtection/DataProtectionBuilderExtensions.cs index 0bbb9168..30b9edbf 100644 --- a/src/Microsoft.AspNetCore.DataProtection/DataProtectionBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.DataProtection/DataProtectionBuilderExtensions.cs @@ -14,6 +14,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Microsoft.Win32; @@ -206,7 +207,7 @@ public static IDataProtectionBuilder PersistKeysToFileSystem(this IDataProtectio builder.Services.AddSingleton>(services => { - var loggerFactory = services.GetRequiredService(); + var loggerFactory = services.GetService() ?? NullLoggerFactory.Instance; return new ConfigureOptions(options => { options.XmlRepository = new FileSystemXmlRepository(directory, loggerFactory); @@ -236,7 +237,7 @@ public static IDataProtectionBuilder PersistKeysToRegistry(this IDataProtectionB builder.Services.AddSingleton>(services => { - var loggerFactory = services.GetRequiredService(); + var loggerFactory = services.GetService() ?? NullLoggerFactory.Instance; return new ConfigureOptions(options => { options.XmlRepository = new RegistryXmlRepository(registryKey, loggerFactory); @@ -266,7 +267,7 @@ public static IDataProtectionBuilder ProtectKeysWithCertificate(this IDataProtec builder.Services.AddSingleton>(services => { - var loggerFactory = services.GetRequiredService(); + var loggerFactory = services.GetService() ?? NullLoggerFactory.Instance; return new ConfigureOptions(options => { options.XmlEncryptor = new CertificateXmlEncryptor(certificate, loggerFactory); @@ -306,7 +307,7 @@ public static IDataProtectionBuilder ProtectKeysWithCertificate(this IDataProtec builder.Services.AddSingleton>(services => { - var loggerFactory = services.GetRequiredService(); + var loggerFactory = services.GetService() ?? NullLoggerFactory.Instance; var certificateResolver = services.GetRequiredService(); return new ConfigureOptions(options => { @@ -357,7 +358,7 @@ public static IDataProtectionBuilder ProtectKeysWithDpapi(this IDataProtectionBu builder.Services.AddSingleton>(services => { - var loggerFactory = services.GetRequiredService(); + var loggerFactory = services.GetService() ?? NullLoggerFactory.Instance; return new ConfigureOptions(options => { CryptoUtil.AssertPlatformIsWindows(); @@ -419,7 +420,7 @@ public static IDataProtectionBuilder ProtectKeysWithDpapiNG(this IDataProtection builder.Services.AddSingleton>(services => { - var loggerFactory = services.GetRequiredService(); + var loggerFactory = services.GetService() ?? NullLoggerFactory.Instance; return new ConfigureOptions(options => { CryptoUtil.AssertPlatformIsWindows8OrLater(); diff --git a/src/Microsoft.AspNetCore.DataProtection/DataProtectionProviderFactory.cs b/src/Microsoft.AspNetCore.DataProtection/DataProtectionProviderFactory.cs deleted file mode 100644 index 4f05478c..00000000 --- a/src/Microsoft.AspNetCore.DataProtection/DataProtectionProviderFactory.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; - -namespace Microsoft.AspNetCore.DataProtection -{ - internal static class DataProtectionProviderFactory - { - public static ILoggerFactory GetDefaultLoggerFactory() - { - return NullLoggerFactory.Instance; - } - } -} diff --git a/src/Microsoft.AspNetCore.DataProtection/DataProtectionServiceCollectionExtensions.cs b/src/Microsoft.AspNetCore.DataProtection/DataProtectionServiceCollectionExtensions.cs index 0df59732..e951736e 100644 --- a/src/Microsoft.AspNetCore.DataProtection/DataProtectionServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNetCore.DataProtection/DataProtectionServiceCollectionExtensions.cs @@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; namespace Microsoft.Extensions.DependencyInjection @@ -64,8 +65,6 @@ public static IDataProtectionBuilder AddDataProtection(this IServiceCollection s private static void AddDataProtectionServices(IServiceCollection services) { - services.TryAddSingleton(DataProtectionProviderFactory.GetDefaultLoggerFactory()); - if (OSVersionUtil.IsWindows()) { services.TryAddSingleton(); @@ -88,10 +87,9 @@ private static void AddDataProtectionServices(IServiceCollection services) { var dpOptions = s.GetRequiredService>(); var keyRingProvider = s.GetRequiredService(); - var loggerFactory = s.GetRequiredService(); + var loggerFactory = s.GetService() ?? NullLoggerFactory.Instance; - IDataProtectionProvider dataProtectionProvider = null; - dataProtectionProvider = new KeyRingBasedDataProtectionProvider(keyRingProvider, loggerFactory); + IDataProtectionProvider dataProtectionProvider = new KeyRingBasedDataProtectionProvider(keyRingProvider, loggerFactory); // Link the provider to the supplied discriminator if (!string.IsNullOrEmpty(dpOptions.Value.ApplicationDiscriminator)) diff --git a/src/Microsoft.AspNetCore.DataProtection/EphemeralDataProtectionProvider.cs b/src/Microsoft.AspNetCore.DataProtection/EphemeralDataProtectionProvider.cs index 93cb0215..587b0ebf 100644 --- a/src/Microsoft.AspNetCore.DataProtection/EphemeralDataProtectionProvider.cs +++ b/src/Microsoft.AspNetCore.DataProtection/EphemeralDataProtectionProvider.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.DataProtection.KeyManagement; using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace Microsoft.AspNetCore.DataProtection { @@ -24,11 +25,23 @@ public sealed class EphemeralDataProtectionProvider : IDataProtectionProvider private readonly KeyRingBasedDataProtectionProvider _dataProtectionProvider; /// - /// Creates an ephemeral , optionally providing - /// services (such as logging) for consumption by the provider. + /// Creates an ephemeral . /// + public EphemeralDataProtectionProvider() + : this (NullLoggerFactory.Instance) + { } + + /// + /// Creates an ephemeral with logging. + /// + /// The . public EphemeralDataProtectionProvider(ILoggerFactory loggerFactory) { + if (loggerFactory == null) + { + throw new ArgumentNullException(nameof(loggerFactory)); + } + IKeyRingProvider keyringProvider; if (OSVersionUtil.IsWindows()) { diff --git a/src/Microsoft.AspNetCore.DataProtection/Internal/DataProtectionStartupFilter.cs b/src/Microsoft.AspNetCore.DataProtection/Internal/DataProtectionStartupFilter.cs index f2abbae5..d9faa5b0 100644 --- a/src/Microsoft.AspNetCore.DataProtection/Internal/DataProtectionStartupFilter.cs +++ b/src/Microsoft.AspNetCore.DataProtection/Internal/DataProtectionStartupFilter.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace Microsoft.AspNetCore.DataProtection.Internal { @@ -14,6 +15,10 @@ internal class DataProtectionStartupFilter : IStartupFilter private readonly IKeyRingProvider _keyRingProvider; private readonly ILogger _logger; + public DataProtectionStartupFilter(IKeyRingProvider keyRingProvider) + : this(keyRingProvider, NullLoggerFactory.Instance) + { } + public DataProtectionStartupFilter(IKeyRingProvider keyRingProvider, ILoggerFactory loggerFactory) { _keyRingProvider = keyRingProvider; diff --git a/src/Microsoft.AspNetCore.DataProtection/Internal/KeyManagementOptionsSetup.cs b/src/Microsoft.AspNetCore.DataProtection/Internal/KeyManagementOptionsSetup.cs index 1f72510e..a197b7ce 100644 --- a/src/Microsoft.AspNetCore.DataProtection/Internal/KeyManagementOptionsSetup.cs +++ b/src/Microsoft.AspNetCore.DataProtection/Internal/KeyManagementOptionsSetup.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; using Microsoft.AspNetCore.DataProtection.KeyManagement; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.DataProtection.Internal @@ -15,7 +16,18 @@ internal class KeyManagementOptionsSetup : IConfigureOptions private readonly TimeSpan _maxServerToServerClockSkew; + public DefaultKeyResolver(IOptions keyManagementOptions) + : this(keyManagementOptions, NullLoggerFactory.Instance) + { } + public DefaultKeyResolver(IOptions keyManagementOptions, ILoggerFactory loggerFactory) { _keyPropagationWindow = keyManagementOptions.Value.KeyPropagationWindow; diff --git a/src/Microsoft.AspNetCore.DataProtection/KeyManagement/KeyRingProvider.cs b/src/Microsoft.AspNetCore.DataProtection/KeyManagement/KeyRingProvider.cs index 8b0b25e7..e407ae62 100644 --- a/src/Microsoft.AspNetCore.DataProtection/KeyManagement/KeyRingProvider.cs +++ b/src/Microsoft.AspNetCore.DataProtection/KeyManagement/KeyRingProvider.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Cryptography; using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.DataProtection.KeyManagement @@ -16,7 +17,6 @@ internal sealed class KeyRingProvider : ICacheableKeyRingProvider, IKeyRingProvi { private CacheableKeyRing _cacheableKeyRing; private readonly object _cacheableKeyRingLockObj = new object(); - private readonly ICacheableKeyRingProvider _cacheableKeyRingProvider; private readonly IDefaultKeyResolver _defaultKeyResolver; private readonly KeyManagementOptions _keyManagementOptions; private readonly IKeyManager _keyManager; @@ -25,31 +25,31 @@ internal sealed class KeyRingProvider : ICacheableKeyRingProvider, IKeyRingProvi public KeyRingProvider( IKeyManager keyManager, IOptions keyManagementOptions, - IDefaultKeyResolver defaultKeyResolver, - ILoggerFactory loggerFactory) + IDefaultKeyResolver defaultKeyResolver) : this( keyManager, keyManagementOptions, - cacheableKeyRingProvider: null, - defaultKeyResolver: defaultKeyResolver, - loggerFactory: loggerFactory) + defaultKeyResolver, + NullLoggerFactory.Instance) { } public KeyRingProvider( IKeyManager keyManager, IOptions keyManagementOptions, - ICacheableKeyRingProvider cacheableKeyRingProvider, IDefaultKeyResolver defaultKeyResolver, ILoggerFactory loggerFactory) { _keyManagementOptions = new KeyManagementOptions(keyManagementOptions.Value); // clone so new instance is immutable _keyManager = keyManager; - _cacheableKeyRingProvider = cacheableKeyRingProvider ?? this; + CacheableKeyRingProvider = this; _defaultKeyResolver = defaultKeyResolver; _logger = loggerFactory.CreateLogger(); } + // for testing + internal ICacheableKeyRingProvider CacheableKeyRingProvider { get; set; } + private CacheableKeyRing CreateCacheableKeyRingCore(DateTimeOffset now, IKey keyJustAdded) { // Refresh the list of all keys @@ -183,7 +183,7 @@ internal IKeyRing GetCurrentKeyRingCore(DateTime utcNow) try { - newCacheableKeyRing = _cacheableKeyRingProvider.GetCacheableKeyRing(utcNow); + newCacheableKeyRing = CacheableKeyRingProvider.GetCacheableKeyRing(utcNow); } catch (Exception ex) { diff --git a/src/Microsoft.AspNetCore.DataProtection/KeyManagement/XmlKeyManager.cs b/src/Microsoft.AspNetCore.DataProtection/KeyManagement/XmlKeyManager.cs index b68a997c..66e7a96d 100644 --- a/src/Microsoft.AspNetCore.DataProtection/KeyManagement/XmlKeyManager.cs +++ b/src/Microsoft.AspNetCore.DataProtection/KeyManagement/XmlKeyManager.cs @@ -20,6 +20,7 @@ using Microsoft.AspNetCore.DataProtection.Repositories; using Microsoft.AspNetCore.DataProtection.XmlEncryption; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Microsoft.Win32; @@ -55,6 +56,15 @@ public sealed class XmlKeyManager : IKeyManager, IInternalXmlKeyManager private CancellationTokenSource _cacheExpirationTokenSource; + /// + /// Creates an . + /// + /// The instance that provides the configuration. + /// The . + public XmlKeyManager(IOptions keyManagementOptions, IActivator activator) + : this (keyManagementOptions, activator, NullLoggerFactory.Instance) + { } + /// /// Creates an . /// @@ -63,7 +73,7 @@ public sealed class XmlKeyManager : IKeyManager, IInternalXmlKeyManager /// The . public XmlKeyManager(IOptions keyManagementOptions, IActivator activator, ILoggerFactory loggerFactory) { - _loggerFactory = loggerFactory; + _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); _logger = _loggerFactory.CreateLogger(); KeyRepository = keyManagementOptions.Value.XmlRepository; diff --git a/src/Microsoft.AspNetCore.DataProtection/RegistryPolicyResolver.cs b/src/Microsoft.AspNetCore.DataProtection/RegistryPolicyResolver.cs index da5b3357..a6f63ee9 100644 --- a/src/Microsoft.AspNetCore.DataProtection/RegistryPolicyResolver.cs +++ b/src/Microsoft.AspNetCore.DataProtection/RegistryPolicyResolver.cs @@ -10,7 +10,6 @@ using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel; using Microsoft.AspNetCore.DataProtection.Internal; using Microsoft.AspNetCore.DataProtection.KeyManagement; -using Microsoft.Extensions.Logging; using Microsoft.Win32; namespace Microsoft.AspNetCore.DataProtection @@ -22,20 +21,17 @@ internal sealed class RegistryPolicyResolver { private readonly Func _getPolicyRegKey; private readonly IActivator _activator; - private readonly ILoggerFactory _loggerFactory; - public RegistryPolicyResolver(IActivator activator, ILoggerFactory loggerFactory) + public RegistryPolicyResolver(IActivator activator) { _getPolicyRegKey = () => Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\DotNetPackages\Microsoft.AspNetCore.DataProtection"); _activator = activator; - _loggerFactory = loggerFactory; } - internal RegistryPolicyResolver(RegistryKey policyRegKey, IActivator activator, ILoggerFactory loggerFactory) + internal RegistryPolicyResolver(RegistryKey policyRegKey, IActivator activator) { _getPolicyRegKey = () => policyRegKey; _activator = activator; - _loggerFactory = loggerFactory; } // populates an options object from values stored in the registry @@ -95,10 +91,8 @@ private static List ReadKeyEscrowSinks(RegistryKey key) /// /// Returns a from the default registry location. /// - public static RegistryPolicy ResolveDefaultPolicy(IActivator activator, ILoggerFactory loggerFactory) - { - return new RegistryPolicyResolver(activator, loggerFactory).ResolvePolicy(); - } + public static RegistryPolicy ResolveDefaultPolicy(IActivator activator) + => new RegistryPolicyResolver(activator).ResolvePolicy(); internal RegistryPolicy ResolvePolicy() { diff --git a/src/Microsoft.AspNetCore.DataProtection/TypeForwardingActivator.cs b/src/Microsoft.AspNetCore.DataProtection/TypeForwardingActivator.cs index 311d4ed4..bf3113ea 100644 --- a/src/Microsoft.AspNetCore.DataProtection/TypeForwardingActivator.cs +++ b/src/Microsoft.AspNetCore.DataProtection/TypeForwardingActivator.cs @@ -4,6 +4,7 @@ using System; using System.Text.RegularExpressions; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace Microsoft.AspNetCore.DataProtection { @@ -15,7 +16,7 @@ internal class TypeForwardingActivator : SimpleActivator private static readonly Regex _versionPattern = new Regex(@",\s?Version=[0-9]+(\.[0-9]+){0,3}", RegexOptions.Compiled, TimeSpan.FromSeconds(2)); public TypeForwardingActivator(IServiceProvider services) - : this(services, DataProtectionProviderFactory.GetDefaultLoggerFactory()) + : this(services, NullLoggerFactory.Instance) { } diff --git a/src/Microsoft.AspNetCore.DataProtection/breakingchanges.netcore.json b/src/Microsoft.AspNetCore.DataProtection/breakingchanges.netcore.json index 81b60f18..2c1b337c 100644 --- a/src/Microsoft.AspNetCore.DataProtection/breakingchanges.netcore.json +++ b/src/Microsoft.AspNetCore.DataProtection/breakingchanges.netcore.json @@ -79,11 +79,6 @@ "MemberId": "public .ctor(Microsoft.Win32.RegistryKey registryKey, System.IServiceProvider services)", "Kind": "Removal" }, - { - "TypeId": "public sealed class Microsoft.AspNetCore.DataProtection.EphemeralDataProtectionProvider : Microsoft.AspNetCore.DataProtection.IDataProtectionProvider", - "MemberId": "public .ctor()", - "Kind": "Removal" - }, { "TypeId": "public sealed class Microsoft.AspNetCore.DataProtection.EphemeralDataProtectionProvider : Microsoft.AspNetCore.DataProtection.IDataProtectionProvider", "MemberId": "public .ctor(System.IServiceProvider services)", @@ -244,4 +239,4 @@ "MemberId": "Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor CreateEncryptor()", "Kind": "Addition" } - ] \ No newline at end of file + ] diff --git a/test/Microsoft.AspNetCore.DataProtection.Test/EphemeralDataProtectionProviderTests.cs b/test/Microsoft.AspNetCore.DataProtection.Test/EphemeralDataProtectionProviderTests.cs index dc7dc642..d42fe211 100644 --- a/test/Microsoft.AspNetCore.DataProtection.Test/EphemeralDataProtectionProviderTests.cs +++ b/test/Microsoft.AspNetCore.DataProtection.Test/EphemeralDataProtectionProviderTests.cs @@ -15,7 +15,7 @@ public class EphemeralDataProtectionProviderTests public void DifferentProvider_SamePurpose_DoesNotRoundTripData() { // Arrange - var dataProtector1 = new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("purpose"); + var dataProtector1 = new EphemeralDataProtectionProvider().CreateProtector("purpose"); var dataProtector2 = new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("purpose"); byte[] bytes = Encoding.UTF8.GetBytes("Hello there!"); diff --git a/test/Microsoft.AspNetCore.DataProtection.Test/Internal/KeyManagementOptionsSetupTest.cs b/test/Microsoft.AspNetCore.DataProtection.Test/Internal/KeyManagementOptionsSetupTest.cs index 6de0c195..ae49c7ed 100644 --- a/test/Microsoft.AspNetCore.DataProtection.Test/Internal/KeyManagementOptionsSetupTest.cs +++ b/test/Microsoft.AspNetCore.DataProtection.Test/Internal/KeyManagementOptionsSetupTest.cs @@ -89,8 +89,7 @@ private static void RunTest(Dictionary regValues, KeyManagementO var policyResolver = new RegistryPolicyResolver( registryKey, - activator: SimpleActivator.DefaultWithoutServices, - loggerFactory: NullLoggerFactory.Instance); + activator: SimpleActivator.DefaultWithoutServices); var setup = new KeyManagementOptionsSetup(NullLoggerFactory.Instance, policyResolver); diff --git a/test/Microsoft.AspNetCore.DataProtection.Test/KeyManagement/KeyRingProviderTests.cs b/test/Microsoft.AspNetCore.DataProtection.Test/KeyManagement/KeyRingProviderTests.cs index 56549438..8582ed83 100644 --- a/test/Microsoft.AspNetCore.DataProtection.Test/KeyManagement/KeyRingProviderTests.cs +++ b/test/Microsoft.AspNetCore.DataProtection.Test/KeyManagement/KeyRingProviderTests.cs @@ -45,7 +45,7 @@ public void CreateCacheableKeyRing_NoGenerationRequired_DefaultKeyExpiresAfterRe ShouldGenerateNewKey = false }) }); - + // Act var cacheableKeyRing = keyRingProvider.GetCacheableKeyRing(now); @@ -597,9 +597,11 @@ private static KeyRingProvider CreateKeyRingProvider(ICacheableKeyRingProvider c return new KeyRingProvider( keyManager: null, keyManagementOptions: Options.Create(options), - cacheableKeyRingProvider: cacheableKeyRingProvider, defaultKeyResolver: null, - loggerFactory: NullLoggerFactory.Instance); + loggerFactory: NullLoggerFactory.Instance) + { + CacheableKeyRingProvider = cacheableKeyRingProvider + }; } private static ICacheableKeyRingProvider CreateKeyRingProvider(IKeyManager keyManager, IDefaultKeyResolver defaultKeyResolver, KeyManagementOptions keyManagementOptions= null) @@ -612,7 +614,6 @@ private static ICacheableKeyRingProvider CreateKeyRingProvider(IKeyManager keyMa return new KeyRingProvider( keyManager: keyManager, keyManagementOptions: Options.Create(keyManagementOptions), - cacheableKeyRingProvider: null, defaultKeyResolver: defaultKeyResolver, loggerFactory: NullLoggerFactory.Instance); } diff --git a/test/Microsoft.AspNetCore.DataProtection.Test/RegistryPolicyResolverTests.cs b/test/Microsoft.AspNetCore.DataProtection.Test/RegistryPolicyResolverTests.cs index 3ce7ee9f..d2de2cde 100644 --- a/test/Microsoft.AspNetCore.DataProtection.Test/RegistryPolicyResolverTests.cs +++ b/test/Microsoft.AspNetCore.DataProtection.Test/RegistryPolicyResolverTests.cs @@ -251,8 +251,7 @@ private static RegistryPolicy RunTestWithRegValues(Dictionary re var policyResolver = new RegistryPolicyResolver( registryKey, - activator: SimpleActivator.DefaultWithoutServices, - loggerFactory: NullLoggerFactory.Instance); + activator: SimpleActivator.DefaultWithoutServices); return policyResolver.ResolvePolicy(); }); diff --git a/test/Microsoft.AspNetCore.DataProtection.Test/ServiceCollectionTests.cs b/test/Microsoft.AspNetCore.DataProtection.Test/ServiceCollectionTests.cs new file mode 100644 index 00000000..ad05973c --- /dev/null +++ b/test/Microsoft.AspNetCore.DataProtection.Test/ServiceCollectionTests.cs @@ -0,0 +1,67 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Xunit; + +namespace Microsoft.AspNetCore.DataProtection +{ + public class ServiceCollectionTests + { + [Fact] + public void AddsOptions() + { + var services = new ServiceCollection() + .AddDataProtection() + .Services + .BuildServiceProvider(); + + Assert.NotNull(services.GetService>()); + } + + [Fact] + public void DoesNotOverrideLogging() + { + var services1 = new ServiceCollection() + .AddLogging() + .AddDataProtection() + .Services + .BuildServiceProvider(); + + var services2 = new ServiceCollection() + .AddDataProtection() + .Services + .AddLogging() + .BuildServiceProvider(); + + Assert.Equal( + services1.GetRequiredService().GetType(), + services2.GetRequiredService().GetType()); + } + + [Fact] + public void CanResolveAllRegisteredServices() + { + var serviceCollection = new ServiceCollection() + .AddDataProtection() + .Services; + var services = serviceCollection.BuildServiceProvider(validateScopes: true); + + Assert.Null(services.GetService()); + + foreach (var descriptor in serviceCollection) + { + if (descriptor.ServiceType.Assembly.GetName().Name == "Microsoft.Extensions.Options") + { + // ignore any descriptors added by the call to .AddOptions() + continue; + } + + Assert.NotNull(services.GetService(descriptor.ServiceType)); + } + } + } +}