public KeyVaultSecretProvider(IKeyVaultAuthentication authentication, IKeyVaultConfiguration vaultConfiguration, KeyVaultOptions options, ILogger <KeyVaultSecretProvider> logger) { Guard.NotNull(vaultConfiguration, nameof(vaultConfiguration), "Requires a Azure Key Vault configuration to setup the secret provider"); Guard.NotNull(authentication, nameof(authentication), "Requires an Azure Key Vault authentication instance to authenticate with the vault"); VaultUri = $"{vaultConfiguration.VaultUri.Scheme}://{vaultConfiguration.VaultUri.Host}"; _authentication = authentication; _options = options; _isUsingAzureSdk = false; Logger = logger ?? NullLogger <KeyVaultSecretProvider> .Instance; }
/// <summary> /// Initializes a new instance of the <see cref="KeyVaultSecretProvider"/> class. /// </summary> /// <param name="tokenCredential">The requested authentication type for connecting to the Azure Key Vault instance</param> /// <param name="vaultConfiguration">Configuration related to the Azure Key Vault instance to use</param> /// <param name="options">The additional options to configure the provider.</param> /// <param name="logger">The logger to write diagnostic trace messages during the interaction with the Azure Key Vault.</param> /// <exception cref="ArgumentNullException">The <paramref name="tokenCredential"/> cannot be <c>null</c>.</exception> /// <exception cref="ArgumentNullException">The <paramref name="vaultConfiguration"/> cannot be <c>null</c>.</exception> public KeyVaultSecretProvider(TokenCredential tokenCredential, IKeyVaultConfiguration vaultConfiguration, KeyVaultOptions options, ILogger <KeyVaultSecretProvider> logger) { Guard.NotNull(vaultConfiguration, nameof(vaultConfiguration), "Requires a Azure Key Vault configuration to setup the secret provider"); Guard.NotNull(tokenCredential, nameof(tokenCredential), "Requires an Azure Key Vault authentication instance to authenticate with the vault"); VaultUri = $"{vaultConfiguration.VaultUri.Scheme}://{vaultConfiguration.VaultUri.Host}"; _secretClient = new SecretClient(vaultConfiguration.VaultUri, tokenCredential); _options = options; _isUsingAzureSdk = true; Logger = logger ?? NullLogger <KeyVaultSecretProvider> .Instance; }
public void LoadEmptyKeyVaultOptions() { IConfiguration cfg = new ConfigurationBuilder().Build(); KeyVaultOptions actualKv = new(); cfg.Bind("KeyVault", actualKv); var expectedKv = new KeyVaultOptions { Name = string.Empty, IdentityClientId = string.Empty }; actualKv.Should().BeEquivalentTo(expectedKv); }
public KeyVaultSecretProvider(IKeyVaultAuthentication authentication, IKeyVaultConfiguration vaultConfiguration, KeyVaultOptions options, ILogger <KeyVaultSecretProvider> logger) { Guard.NotNull(vaultConfiguration, nameof(vaultConfiguration), "Requires a Azure Key Vault configuration to setup the secret provider"); Guard.NotNull(authentication, nameof(authentication), "Requires an Azure Key Vault authentication instance to authenticate with the vault"); VaultUri = $"{vaultConfiguration.VaultUri.Scheme}://{vaultConfiguration.VaultUri.Host}"; Guard.For <UriFormatException>( () => !VaultUriRegex.IsMatch(VaultUri), "Requires the Azure Key Vault host to be in the right format, see https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#objects-identifiers-and-versioning"); _authentication = authentication; _options = options; _isUsingAzureSdk = false; Logger = logger ?? NullLogger <KeyVaultSecretProvider> .Instance; }
public static IConfigurationBuilder AddCostributeAzureKeyVault(this IConfigurationBuilder builder) { var rootConfig = builder.Build(); var keyVaultOptions = new KeyVaultOptions(); rootConfig.GetSection(typeof(KeyVaultOptions).Name).Bind(keyVaultOptions); var azureServiceTokenProvider = new AzureServiceTokenProvider(); var keyVaultClient = new KeyVaultClient( new KeyVaultClient.AuthenticationCallback( azureServiceTokenProvider.KeyVaultTokenCallback)); builder.AddAzureKeyVault( keyVaultOptions.VaultUri, keyVaultClient, new DefaultKeyVaultSecretManager()); return(builder); }
public void LoadKeyVaultOptions() { IConfiguration cfg = GetConfiguration(); KeyVaultOptions actualKv = new(); cfg.Bind("KeyVault", actualKv); var expectedKv = new KeyVaultOptions { Name = "example-kv", IdentityClientId = "Lorem", ReloadInterval = TimeSpan.FromSeconds((2 * 60) + 15) }; expectedKv.Prefixes.AddRange(new[] { "Example1", "Example2" }); actualKv.Should().BeEquivalentTo(expectedKv); }
public KeyVaultIntegration(KeyVaultOptions options) { SecretClient = new SecretClient(vaultUri: new Uri(options.Url), credential: new DefaultAzureCredential(), options: options.SecretOptions); CertificateClient = new CertificateClient(vaultUri: new Uri(options.Url), credential: new DefaultAzureCredential(), options: options.CertificateOptions); KeyClient = new KeyClient(vaultUri: new Uri(options.Url), credential: new DefaultAzureCredential(), options: options.KeyOptions); }
public static IHostBuilder Create(IConfiguration configuration, bool runAsWindowsService, ILogger logger) { var builder = new HostBuilder(); var serverOptions = new OakproxyServerOptions(); serverOptions.Configure(configuration.GetSection("Server")); var proxyOptions = ConfigurationBinder.Get <ProxyOptions>(configuration); if (!OptionsAreValid(serverOptions, logger, "Server") || !OptionsAreValid(proxyOptions, logger)) { return(null); } var subsystemConfiguration = ConfigurationBinder.Get <HostingSubsystemConfiguration>(configuration.GetSection("Configuration"), binderOptions => binderOptions.BindNonPublicProperties = true) ?? HostingSubsystemConfiguration.Empty(); builder .UseContentRoot(Program.GetExecutableDirectory()) .ConfigureHostConfiguration(builder => builder.AddConfiguration(subsystemConfiguration.Host)); if (runAsWindowsService) { builder.UseWindowsService(); } builder .ConfigureAppConfiguration(builder => builder.AddConfiguration(configuration)) .ConfigureLogging((hostBuilderContext, loggingBuilder) => { if (subsystemConfiguration.Logging.Exists()) { loggingBuilder.AddConfiguration(subsystemConfiguration.Logging); } else { loggingBuilder.AddFilter(null, serverOptions.LogLevelInternal); } if (runAsWindowsService) { loggingBuilder.AddProvider(new DeferringLoggerProvider(new EventLogLoggerProvider(new EventLogSettings { SourceName = "OAKProxy" }))); } else { loggingBuilder.AddConsole(); } }) .UseDefaultServiceProvider((context, options) => { options.ValidateScopes = context.HostingEnvironment.IsDevelopment(); }) .ConfigureServices((context, services) => { services.AddOptions <ProxyOptions>() .Bind(configuration) .ValidateDataAnnotations(); services.AddSingleton(Options.Create(serverOptions)); if (!String.IsNullOrWhiteSpace(serverOptions.ApplicationInsightsKey)) { services.AddApplicationInsightsTelemetry(options => { options.InstrumentationKey = serverOptions.ApplicationInsightsKey; subsystemConfiguration.ApplicationInsights.Bind(options); }); services.AddApplicationInsightsTelemetryProcessor <OakproxyTelemetryProcessor>(); } services.AddTransient <IStartupFilter, HostingPipelineStartup>(); if (serverOptions.UseForwardedHeaders || serverOptions.UseAzureApplicationGateway) { services.Configure <ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.All; options.KnownNetworks.Clear(); options.KnownProxies.Clear(); subsystemConfiguration.ForwardedHeaders.Bind(options); if (serverOptions.UseAzureApplicationGateway) { options.ForwardedHostHeaderName = "X-Original-Host"; } }); } if (serverOptions.KeyManagement != null) { var dataProtectionBuilder = services.AddDataProtection(); var kmOptions = serverOptions.KeyManagement; kmOptions.LoadCertificates(configuration.GetSection(ConfigurationPath.Combine("Server", "KeyManagement"))); if (!String.IsNullOrEmpty(kmOptions.StoreToFilePath)) { var directoryInfo = new DirectoryInfo(kmOptions.StoreToFilePath); if (!directoryInfo.Exists) { throw new DirectoryNotFoundException("The specified key storage directory does not exist."); } dataProtectionBuilder.PersistKeysToFileSystem(directoryInfo); } else if (!String.IsNullOrEmpty(kmOptions.StoreToBlobContainer)) { var blobUri = new Uri(kmOptions.StoreToBlobContainer); if (String.IsNullOrEmpty(blobUri.Query)) { var azureServiceTokenProvider = new AzureServiceTokenProvider(); var tokenAndFrequency = StorageTokenRenewerAsync(azureServiceTokenProvider, CancellationToken.None) .GetAwaiter().GetResult(); TokenCredential tokenCredential = new TokenCredential(tokenAndFrequency.Token, StorageTokenRenewerAsync, azureServiceTokenProvider, tokenAndFrequency.Frequency.Value); var storageCredentials = new StorageCredentials(tokenCredential); var cloudBlockBlob = new CloudBlockBlob(blobUri, storageCredentials); dataProtectionBuilder.PersistKeysToAzureBlobStorage(cloudBlockBlob); } else { dataProtectionBuilder.PersistKeysToAzureBlobStorage(blobUri); } } if (!String.IsNullOrEmpty(kmOptions.ProtectWithKeyVaultKey)) { var keyVaultSection = configuration.GetSection(ConfigurationPath.Combine("Server", "KeyVault")); var kvOptions = new KeyVaultOptions(keyVaultSection); var keyIdBuilder = new UriBuilder(kvOptions.VaultUri) { Path = $"/keys/${kmOptions.ProtectWithKeyVaultKey}" }; var keyId = keyIdBuilder.Uri.ToString(); if (kvOptions.ClientId == null) { // Use Managed Identity var azureServiceTokenProvider = new AzureServiceTokenProvider(); var authenticationCallback = new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback); dataProtectionBuilder.ProtectKeysWithAzureKeyVault(new KeyVaultClient(authenticationCallback), keyId); } else { if (kvOptions.ClientSecret != null) { dataProtectionBuilder.ProtectKeysWithAzureKeyVault(keyId, kvOptions.ClientId, kvOptions.ClientSecret); } else if (kvOptions.Certificate != null) { dataProtectionBuilder.ProtectKeysWithAzureKeyVault(keyId, kvOptions.ClientId, kvOptions.Certificate); } } } else if (kmOptions.ProtectWithCertificate != null) { dataProtectionBuilder.ProtectKeysWithCertificate(kmOptions.ProtectWithCertificate); if (kmOptions.UnprotectWithCertificates != null) { dataProtectionBuilder.UnprotectKeysWithAnyCertificate(kmOptions.UnprotectWithCertificates); } } else if (kmOptions.ProtectWithDpapiNg != null) { if (kmOptions.ProtectWithDpapiNg.UseSelfRule) { dataProtectionBuilder.ProtectKeysWithDpapiNG(); } else { dataProtectionBuilder.ProtectKeysWithDpapiNG(kmOptions.ProtectWithDpapiNg.DescriptorRule, kmOptions.ProtectWithDpapiNg.DescriptorFlags); } } else { throw new Exception("Unvalidated options would have allowed for unprotected key storage."); } } services.AddHttpContextAccessor(); services.AddHealthChecks(); services.AddOakproxy(proxyOptions); }) .ConfigureWebHost(configure => { configure.UseUrls(serverOptions.Urls); configure.UseKestrel((builderContext, options) => { options.Configure(subsystemConfiguration.Kestrel); if (serverOptions.HttpsCertificate != null) { options.ConfigureHttpsDefaults(configureHttps => configureHttps.ServerCertificate = serverOptions.HttpsCertificate); } }); configure.Configure(builder => builder.UseOakproxy()); }); return(builder); }
public ConfigurationOptions() { Data = new DatabaseOptions(); KeyVault = new KeyVaultOptions(); }
public SecretAccess(IOptions <KeyVaultOptions> keyVaultOptions) { _keyVaultOptions = keyVaultOptions.Value; _kvURL = $"https://{_keyVaultOptions.KeyVaultName}.vault.azure.net"; }