如何在.NET 7 Web Api中使用clientId和thumbprint对Azure Key Vault请求进行身份验证?

huangapple go评论97阅读模式
英文:

How to authenticate Azure Key Vault request using clientId and thumbprint in .NET 7 Web Api?

问题

我可以帮你修改这个方法,以便使用 ClientIdThumbprint 进行 Azure Key Vault 的身份验证。请查看下面的修改后的代码:

  1. public static IConfigurationBuilder AddAzureKeyVaultConfiguration(this IConfigurationBuilder configurationBuilder, IWebHostEnvironment hostingEnvironment)
  2. {
  3. if (!hostingEnvironment.IsEnvironment("Localhost"))
  4. {
  5. var builtConfig = configurationBuilder.Build();
  6. var keyVaultEndpoint = $"https://{builtConfig["KeyVaultConfigOption:Name"]}.vault.azure.net/";
  7. var clientId = builtConfig["KeyVaultConfigOption:ClientId"];
  8. var thumbprint = builtConfig["KeyVaultConfigOption:Thumbprint"];
  9. var tokenCredential = new ClientCertificateCredential(clientId, thumbprint);
  10. configurationBuilder.AddAzureKeyVault(
  11. new Uri(keyVaultEndpoint),
  12. tokenCredential
  13. );
  14. }
  15. return configurationBuilder;
  16. }

在这个修改后的方法中,我使用了 ClientCertificateCredential 类来创建凭据,其中包括了 ClientIdThumbprint。这将用于 Azure Key Vault 的身份验证。请确保在 appsettings.json 文件中设置了正确的 ClientIdThumbprint 值。

希望这可以帮助你实现所需的修改。如果你有任何其他问题,请随时提问。

英文:

I have .NET 7 Web Api application where I m using the AddAzureKeyVault method to add Azure Key Vault configurations to my IConfigurationBuilder instance. Currently, I am using the DefaultAzureCredential for authentication.

However, I want to modify this method to authenticate the Key Vault request using clientId and thumbprint. I have access to these values and want to use them for authentication instead of the default credential types.

Here is my current code:

  1. public static IConfigurationBuilder AddAzureKeyVaultConfiguration(this IConfigurationBuilder configurationBuilder, IWebHostEnvironment hostingEnvironment)
  2. {
  3. if (!hostingEnvironment.IsEnvironment("Localhost"))
  4. {
  5. var builtConfig = configurationBuilder.Build();
  6. var keyVaultEndpoint = $"https://{builtConfig["KeyVaultConfigOption:Name"]}.vault.azure.net/";
  7. configurationBuilder.AddAzureKeyVault(
  8. new Uri(keyVaultEndpoint),
  9. new DefaultAzureCredential(new DefaultAzureCredentialOptions
  10. {
  11. ExcludeEnvironmentCredential = true,
  12. ExcludeInteractiveBrowserCredential = true,
  13. ExcludeAzurePowerShellCredential = true,
  14. ExcludeSharedTokenCacheCredential = true,
  15. ExcludeVisualStudioCodeCredential = true,
  16. ExcludeVisualStudioCredential = true,
  17. ExcludeAzureCliCredential = false,
  18. ExcludeManagedIdentityCredential = false,
  19. })
  20. );
  21. }
  22. return configurationBuilder;
  23. }

}

Program.cs

  1. var builder = WebApplication.CreateBuilder(args);
  2. {
  3. // Environment configuration
  4. var configuration = builder.Configuration;
  5. var env = builder.Environment;
  6. configuration.AddAppConfiguration(env);
  7. // Add azure key vault configuration
  8. builder.Configuration.AddAzureKeyVaultConfiguration(env);
  9. builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<Program>());
  10. builder.Services.AddHttpClient();
  11. builder.Services.AddApplication();
  12. builder.Services.AddInfrastructure(builder.Configuration);
  13. builder.Services.AddHelpers();
  14. builder.Services.AddControllers()
  15. // Configures the JSON serialization options for controllers.
  16. .AddJsonOptions(options =>
  17. {
  18. options.JsonSerializerOptions.PropertyNamingPolicy = null;
  19. });
  20. builder.Services.Configure<ApiBehaviorOptions>(options =>
  21. {
  22. options.SuppressModelStateInvalidFilter = true;
  23. });
  24. }
  25. var app = builder.Build();
  26. {
  27. app.UseHttpsRedirection();
  28. // Authentication & Authorization
  29. app.UseAuthentication();
  30. app.UseAuthorization();
  31. app.MapControllers();
  32. app.UseRouting();
  33. app.UseSwaggerWithVersioning();
  34. }
  35. if (app.Environment.IsDevelopment())
  36. {
  37. //DEV configurations
  38. }
  39. app.Run();

appsettings.json

  1. "KeyVaultConfigOption": {
  2. "Name": "{KeyValultName}",
  3. "Url": "https://{KeyVaultName}.vault.azure.net",
  4. "Thumbprint": "",
  5. "ClientId": ""
  6. }

How can I modify this method to authenticate the Azure Key Vault request using ClientId and Thumbprint?

答案1

得分: 1

你可以使用 ClientCertificateCredentialX509Certificate2 对象。

首先,使用指纹来从 X509Store 中查找所需的证书。

英文:

You can use the ClientCertificateCredential along with the X509Certificate2 object.

To first fetch the certificate required, use the thumbprint to find the certificate from the X509Store.

答案2

得分: 0

如Pramod在先前的回答中建议的,我做出了相应的更改,现在我能够使用证书对密钥保管库请求进行身份验证。

  1. public static IConfigurationBuilder AddAzureKeyVaultConfiguration(this IConfigurationBuilder configurationBuilder, IWebHostEnvironment hostingEnvironment)
  2. {
  3. if (!hostingEnvironment.IsEnvironment("Development"))
  4. {
  5. var builtConfig = configurationBuilder.Build();
  6. var keyVaultEndpoint = $"https://{builtConfig["KeyVaultConfigOption:Name"]}.vault.azure.net/";
  7. var clientId = builtConfig["KeyVaultConfigOption:ClientId"];
  8. var thumbprint = builtConfig["KeyVaultConfigOption:Thumbprint"];
  9. var tenantId = builtConfig["KeyVaultConfigOption:TenantId"];
  10. var certificate = GetCertificate(thumbprint);
  11. var clientCertificateCredential = new ClientCertificateCredential(tenantId, clientId, certificate);
  12. configurationBuilder.AddAzureKeyVault(new Uri(keyVaultEndpoint), clientCertificateCredential);
  13. var keyVaultClient = new SecretClient(new Uri(keyVaultEndpoint), clientCertificateCredential);
  14. Task.Run(() => LoadKeysFromKeyVault(configurationBuilder, keyVaultClient)).Wait();
  15. }
  16. return configurationBuilder;
  17. }
  18. private static X509Certificate2 GetCertificate(string thumbprint)
  19. {
  20. var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
  21. store.Open(OpenFlags.ReadOnly);
  22. var cert = store.Certificates.OfType<X509Certificate2>()
  23. .FirstOrDefault(x => x.Thumbprint == thumbprint);
  24. store.Close();
  25. if (cert == null)
  26. throw new InvalidOperationException($"Failed to find the certificate for thumbprint:{thumbprint}");
  27. return cert;
  28. }
  29. private static async Task LoadKeysFromKeyVault(IConfigurationBuilder configurationBuilder, SecretClient keyVaultClient)
  30. {
  31. var serviceBusConfig = configurationBuilder.Build().GetSection(ServiceBusConfigOption.SectionName).Get<ServiceBusConfigOption>();
  32. var propertiesToLoad = new Dictionary<string, string>
  33. {
  34. { $"{ServiceBusConfigOption.SectionName}:{nameof(serviceBusConfig.ConnectionString)}", serviceBusConfig.ConnectionString },
  35. };
  36. foreach (var kvp in propertiesToLoad)
  37. {
  38. var configurationKey = kvp.Key;
  39. var secretName = kvp.Value;
  40. var secret = await keyVaultClient.GetSecretAsync(secretName);
  41. // Modify the configuration to replace the key value
  42. configurationBuilder.Sources.RemoveAt(configurationBuilder.Sources.Count - 1); // Remove the Key Vault source
  43. configurationBuilder.AddInMemoryCollection(new Dictionary<string, string>
  44. {
  45. { configurationKey, secret.Value.Value }
  46. });
  47. }
  48. }
英文:

As Pramod suggested in the previous answer, I made the following changes accordingly and now I am able to authenticate key vault request with certificates.

  1. public static IConfigurationBuilder AddAzureKeyVaultConfiguration(this IConfigurationBuilder configurationBuilder, IWebHostEnvironment hostingEnvironment)
  2. {
  3. if (!hostingEnvironment.IsEnvironment(&quot;Development&quot;))
  4. {
  5. var builtConfig = configurationBuilder.Build();
  6. var keyVaultEndpoint = $&quot;https://{builtConfig[&quot;KeyVaultConfigOption:Name&quot;]}.vault.azure.net/&quot;;
  7. var clientId = builtConfig[&quot;KeyVaultConfigOption:ClientId&quot;];
  8. var thumbprint = builtConfig[&quot;KeyVaultConfigOption:Thumbprint&quot;];
  9. var tenantId = builtConfig[&quot;KeyVaultConfigOption:TenantId&quot;];
  10. var certificate = GetCertificate(thumbprint);
  11. var clientCertificateCredential = new ClientCertificateCredential(tenantId, clientId, certificate);
  12. configurationBuilder.AddAzureKeyVault(new Uri(keyVaultEndpoint), clientCertificateCredential);
  13. var keyVaultClient = new SecretClient(new Uri(keyVaultEndpoint), clientCertificateCredential);
  14. Task.Run(() =&gt; LoadKeysFromKeyVault(configurationBuilder, keyVaultClient)).Wait();
  15. }
  16. return configurationBuilder;
  17. }
  18. private static X509Certificate2 GetCertificate(string thumbprint)
  19. {
  20. var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
  21. store.Open(OpenFlags.ReadOnly);
  22. var cert = store.Certificates.OfType&lt;X509Certificate2&gt;()
  23. .FirstOrDefault(x =&gt; x.Thumbprint == thumbprint);
  24. store.Close();
  25. if (cert == null)
  26. throw new InvalidOperationException($&quot;Failed to find the certificate for thumbprint:{thumbprint}&quot;);
  27. return cert;
  28. }
  29. private static async Task LoadKeysFromKeyVault(IConfigurationBuilder configurationBuilder, SecretClient keyVaultClient)
  30. {
  31. var serviceBusConfig = configurationBuilder.Build().GetSection(ServiceBusConfigOption.SectionName).Get&lt;ServiceBusConfigOption&gt;();
  32. var propertiesToLoad = new Dictionary&lt;string, string&gt;
  33. {
  34. { $&quot;{ServiceBusConfigOption.SectionName}:{nameof(serviceBusConfig.ConnectionString)}&quot;, serviceBusConfig.ConnectionString },
  35. };
  36. foreach (var kvp in propertiesToLoad)
  37. {
  38. var configurationKey = kvp.Key;
  39. var secretName = kvp.Value;
  40. var secret = await keyVaultClient.GetSecretAsync(secretName);
  41. // Modify the configuration to replace the key value
  42. configurationBuilder.Sources.RemoveAt(configurationBuilder.Sources.Count - 1); // Remove the Key Vault source
  43. configurationBuilder.AddInMemoryCollection(new Dictionary&lt;string, string&gt;
  44. {
  45. { configurationKey, secret.Value.Value }
  46. });
  47. }
  48. }

huangapple
  • 本文由 发表于 2023年6月1日 14:58:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76379386.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定