C# 如何使用AzureKeyVault调试ProtectKeys?
尝试使用AzureKeyVault保护密钥时,出现以下错误: 00:01:41错误]读取钥匙圈时出错。 Microsoft.Azure.KeyVault.Models.KeyVault错误异常:操作返回无效的状态代码“禁止” 位于Microsoft.Azure.KeyVault.KeyVaultClient.WrapkeyWithHttpMessageAsync(字符串vaultBaseUrl、字符串keyName、字符串keyVersion、字符串算法、字节[]值、字典`2 CustomHeader、CancellationToken CancellationToken) 位于Microsoft.Azure.KeyVault.KeyVaultClientExtensions.WrapKeyAsync(IKeyVaultClient操作,字符串keyIdentifier,字符串算法,字节[]键,CancellationToken CancellationToken) 位于Microsoft.AspNetCore.DataProtection.AzureKeyVault.AzureKeyVault XmlEncryptor.EncryptAsync(XElement plaintextElement) 位于Microsoft.AspNetCore.DataProtection.AzureKeyVault.AzureKeyVault XmlEncryptor.Encrypt(XElement plaintextElement) 在Microsoft.AspNetCore.DataProtection.XmlEncryption.XmlEncryptionExtensions.EncryptifEssential(IXmlEncryptor encryptor encryptor,XElement元素)上 位于Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IIInternalXMLKeyManager.CreateNewKey(Guid-keyId、DateTimeOffset-creationDate、DateTimeOffset-activationDate、DateTimeOffset-expirationDate) 在Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.CreateNewKey(DateTimeOffset activationDate,DateTimeOffset expirationDate) 在Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.CreateCacheableKeyRingCore(现在是DateTimeOffset,IKey keyJustAdded) 位于Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.ICacheableKeyRingProvider.GetCacheableKeyRing(现在是DateTimeOffset) 位于Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.GetCurrentKeyRingCore(DateTime utcNow) 我尝试使用这样的方法:C# 如何使用AzureKeyVault调试ProtectKeys?,c#,azure,asp.net-core,azure-keyvault,C#,Azure,Asp.net Core,Azure Keyvault,尝试使用AzureKeyVault保护密钥时,出现以下错误: 00:01:41错误]读取钥匙圈时出错。 Microsoft.Azure.KeyVault.Models.KeyVault错误异常:操作返回无效的状态代码“禁止” 位于Microsoft.Azure.KeyVault.KeyVaultClient.WrapkeyWithHttpMessageAsync(字符串vaultBaseUrl、字符串keyName、字符串keyVersion、字符串算法、字节[]值、字典`2 CustomHea
services.AddDataProtection()
.SetApplicationName("APPLICATIONNAME")
.PersistKeysToAzureBlobStorage(container, "keys.xml")
.ProtectKeysWithAzureKeyVault(KeyVaultClientFactory.Create(), "https://KEYVAULTNAME.vault.azure.net/keys/DATAPROTECTIONKEY/");
我检查过的东西:
KeyVaultClientFactory.Create()
返回可以检索机密的有效KeyVault
我现在不知道如何进一步调试它。我想我遗漏了一些明显的东西,欢迎提供任何建议 我建议您更改以下实施方式:
{
"DataProtection": {
"KeyVaultKeyId": "https://mykeyvaultname.vault.azure.net/keys/DataProtectionKey/bfc1bda979bc4081b89ab6f43bad12b8"
}
}
var kvClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(_tokenProvider.KeyVaultTokenCallback));
services.AddDataProtection()
.ProtectKeysWithAzureKeyVault(kvClient, settings.KeyVaultKeyId);
请确保为应用程序提供钥匙库的解包密钥和包裹密钥权限。请注意,t在授予许可后的某个时候需要时间来反映更改
您可以在此处查看参考代码:
附加参考:
我的startup.cs是这样的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using KeyVaultSample.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Azure.KeyVault;
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.AspNetCore.DataProtection.AzureStorage;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.Rest;
using Microsoft.WindowsAzure.Storage.Auth;
namespace KeyVaultSample
{
public class DataProtectionSettings
{
public string KeyVaultKeyId { get; set; }
public string AadTenantId { get; set; }
public string StorageAccountName { get; set; }
public string StorageKeyContainerName { get; set; }
public string StorageKeyBlobName { get; set; }
}
public class Startup
{
private readonly AzureServiceTokenProvider _tokenProvider;
public Startup(IConfiguration configuration)
{
Configuration = configuration;
_tokenProvider = new AzureServiceTokenProvider();
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
var settings = Configuration.GetSection("DataProtection").Get<DataProtectionSettings>();
var kvClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(_tokenProvider.KeyVaultTokenCallback));
services.AddDataProtection()
.ProtectKeysWithAzureKeyVault(kvClient, settings.KeyVaultKeyId);
// Replicates PersistKeysToAzureBlobStorage
// There is no overload to give it the func it ultimately uses
// We need to do that so that we can get refreshed tokens when needed
services.Configure<KeyManagementOptions>(options =>
{
options.XmlRepository = new AzureBlobXmlRepository(() =>
{
// This func is called every time before getting the blob and before modifying the blob
// Get access token for Storage
// User / managed identity needs Blob Data Contributor on the Storage Account (container was not enough)
string accessToken = _tokenProvider.GetAccessTokenAsync("https://storage.azure.com/", tenantId: settings.AadTenantId)
.GetAwaiter()
.GetResult();
// Create blob reference with token
var tokenCredential = new TokenCredential(accessToken);
var storageCredentials = new StorageCredentials(tokenCredential);
var uri = new Uri($"https://{settings.StorageAccountName}.blob.core.windows.net/{settings.StorageKeyContainerName}/{settings.StorageKeyBlobName}");
// Note this func is expected to return a new instance on each call
var blob = new CloudBlockBlob(uri, storageCredentials);
return blob;
});
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc();
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Threading.Tasks;
使用Microsoft.AspNetCore.Builder;
使用Microsoft.AspNetCore.Identity;
使用Microsoft.AspNetCore.Identity.UI;
使用Microsoft.AspNetCore.Hosting;
使用Microsoft.AspNetCore.Http;
使用Microsoft.AspNetCore.HttpsPolicy;
使用Microsoft.AspNetCore.Mvc;
使用Microsoft.EntityFrameworkCore;
使用KeyVaultSample.Data;
使用Microsoft.Extensions.Configuration;
使用Microsoft.Extensions.DependencyInjection;
使用Microsoft.Azure.KeyVault;
使用Microsoft.Azure.Services.AppAuthentication;
使用Microsoft.AspNetCore.DataProtection;
使用Microsoft.AspNetCore.DataProtection.KeyManagement;
使用Microsoft.AspNetCore.DataProtection.AzureStorage;
使用Microsoft.WindowsAzure.Storage.Blob;
使用微软.Rest;
使用Microsoft.WindowsAzure.Storage.Auth;
名称空间KeyVaultSample
{
公共类数据保护设置
{
公共字符串KeyVaultKeyId{get;set;}
公共字符串AadTenantId{get;set;}
公共字符串StorageAccountName{get;set;}
公共字符串StorageKeyContainerName{get;set;}
公共字符串StorageKeyBlobName{get;set;}
}
公营创业
{
专用只读AzureServiceTokenProvider\u tokenProvider;
公共启动(IConfiguration配置)
{
配置=配置;
_tokenProvider=新AzureServiceTokenProvider();
}
公共IConfiguration配置{get;}
//此方法由运行时调用。请使用此方法将服务添加到容器中。
public void配置服务(IServiceCollection服务)
{
配置(选项=>
{
//此lambda确定给定请求是否需要非必要cookie的用户同意。
options.checkApprovered=context=>true;
options.MinimumSameSitePolicy=SameSiteMode.None;
});
var settings=Configuration.GetSection(“数据保护”).Get();
var kvClient=new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(_tokenProvider.KeyVaultTokenCallback));
services.AddDataProtection()
.ProtectKeysWithAzureKeyVault(kvClient,settings.KeyVault KeyId);
//复制PersistKeysAzureBlobstorage
//没有重载来提供它最终使用的函数
//我们需要这样做,以便在需要时获得刷新的令牌
配置(选项=>
{
options.XmlRepository=新AzureBlobXmlRepository(()=>
{
//每次在获取blob和修改blob之前都会调用此func
//获取存储的访问令牌
//