如何向 Azure C# SecretClient 提供凭据 (DefaultAzureCredential)?它似乎忽略了凭据和 RBAC 并抛出 403
How to give credentials (DefaultAzureCredential) to Azure C# SecretClient? It seems to ignore credentials and RBAC and throw 403
我有一个带有密钥保管库的 Azure Web 应用程序。我想使用 C# 应用程序将机密存储在密钥保管库中。
- 我有两个订阅:开发订阅和生产订阅。
- 每个都包含一个密钥库。
- 两个密钥保管库都使用“Azure 基于角色的控制”权限模型。
- 我的帐户对两个密钥保管库都有“所有者”和“密钥保管库保密官”角色。
- 我可以从 Azure GUI 或 azure-cli (
az keyvault secret set
) 将机密很好地上传到这两种环境。
我的 C# 应用程序可以将机密上传到开发,但不能上传到生产,无论我提供什么凭据。在生产中它总是抛出以下错误:
Azure.RequestFailedException: Service request failed.
Status: 403 (Forbidden)
Content:
{"error":{"code":"Forbidden","message":
"Caller is not authorized to perform action on resource.\r\n
If role assignments, deny assignments or role definitions were changed recently, please observe propagation time.\r\n
Caller: appid=<GUID>;oid=<GUID>;iss=https://sts.windows.net/<GUID>/\r\n
Action: 'Microsoft.KeyVault/vaults/secrets/setSecret/action'\r\n
Resource: '<path to my secret>'\r\n
Assignment: (not found)\r\n
Vault: <name>;location=westeurope\r\n",
"innererror":{"code":"ForbiddenByRbac"}}}
错误消息说它与RBAC有关。我不明白它从哪里获得权利。我正在从 PowerShell 提示符调用应用程序。我以为它会从 PowerShell 获取我的权限,但我做 az login
或 az logout
或 az account set
都没有区别。无论我做什么,它都可以很好地上传到开发,但不能上传到生产。
我用的是classAzure.Security.KeyVault.Secrets.SecretClient
。我是这样创建的:
private SecretClient CreateSecretClient() =>
new(
new Uri($"https://{_keyVaultName}.vault.azure.net/"),
new DefaultAzureCredential(),
new SecretClientOptions
{
Retry =
{
Delay = TimeSpan.FromSeconds(2),
MaxDelay = TimeSpan.FromSeconds(16),
MaxRetries = 5,
Mode = RetryMode.Exponential
}
});
我是这样写秘籍的:
var keyVaultSecret = new KeyVaultSecret(secretName, value);
await _secretClient.SetSecretAsync(keyVaultSecret, ct);
我也试过给它一个托管身份(它应该有权访问生产而不是开发):
new DefaultAzureCredential(
new DefaultAzureCredentialOptions
{
ManagedIdentityClientId = <GUID>
})
还是一样的结果。它愿意写给开发,而不是生产。我什至试图给它一个 ManagedIdentityClientId
,这是胡说八道,不指向任何现有的托管身份。结果相同。
在我看来,我的 SecretClient
似乎忽略了其分配的凭据对象和 PowerShell 会话中的权限。它会凭空变出它的权限吗?无论我做什么,它如何能够写入我的开发环境?我如何让它访问我的其他环境?
我找到了一个有效的修复方法。我可以使用 InteractiveBrowserCredential
而不是 DefaultAzureCredential
.
private SecretClient CreateSecretClient() =>
new(
new Uri($"https://{_keyVaultName}.vault.azure.net/"),
new InteractiveBrowserCredential(),
new SecretClientOptions
{
Retry =
{
Delay = TimeSpan.FromSeconds(2),
MaxDelay = TimeSpan.FromSeconds(16),
MaxRetries = 5,
Mode = RetryMode.Exponential
}
});
我可能还可以使用其他类型的 TokenCredential
,如下所列:https://docs.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet
我有一个带有密钥保管库的 Azure Web 应用程序。我想使用 C# 应用程序将机密存储在密钥保管库中。
- 我有两个订阅:开发订阅和生产订阅。
- 每个都包含一个密钥库。
- 两个密钥保管库都使用“Azure 基于角色的控制”权限模型。
- 我的帐户对两个密钥保管库都有“所有者”和“密钥保管库保密官”角色。
- 我可以从 Azure GUI 或 azure-cli (
az keyvault secret set
) 将机密很好地上传到这两种环境。
我的 C# 应用程序可以将机密上传到开发,但不能上传到生产,无论我提供什么凭据。在生产中它总是抛出以下错误:
Azure.RequestFailedException: Service request failed.
Status: 403 (Forbidden)
Content:
{"error":{"code":"Forbidden","message":
"Caller is not authorized to perform action on resource.\r\n
If role assignments, deny assignments or role definitions were changed recently, please observe propagation time.\r\n
Caller: appid=<GUID>;oid=<GUID>;iss=https://sts.windows.net/<GUID>/\r\n
Action: 'Microsoft.KeyVault/vaults/secrets/setSecret/action'\r\n
Resource: '<path to my secret>'\r\n
Assignment: (not found)\r\n
Vault: <name>;location=westeurope\r\n",
"innererror":{"code":"ForbiddenByRbac"}}}
错误消息说它与RBAC有关。我不明白它从哪里获得权利。我正在从 PowerShell 提示符调用应用程序。我以为它会从 PowerShell 获取我的权限,但我做 az login
或 az logout
或 az account set
都没有区别。无论我做什么,它都可以很好地上传到开发,但不能上传到生产。
我用的是classAzure.Security.KeyVault.Secrets.SecretClient
。我是这样创建的:
private SecretClient CreateSecretClient() =>
new(
new Uri($"https://{_keyVaultName}.vault.azure.net/"),
new DefaultAzureCredential(),
new SecretClientOptions
{
Retry =
{
Delay = TimeSpan.FromSeconds(2),
MaxDelay = TimeSpan.FromSeconds(16),
MaxRetries = 5,
Mode = RetryMode.Exponential
}
});
我是这样写秘籍的:
var keyVaultSecret = new KeyVaultSecret(secretName, value);
await _secretClient.SetSecretAsync(keyVaultSecret, ct);
我也试过给它一个托管身份(它应该有权访问生产而不是开发):
new DefaultAzureCredential(
new DefaultAzureCredentialOptions
{
ManagedIdentityClientId = <GUID>
})
还是一样的结果。它愿意写给开发,而不是生产。我什至试图给它一个 ManagedIdentityClientId
,这是胡说八道,不指向任何现有的托管身份。结果相同。
在我看来,我的 SecretClient
似乎忽略了其分配的凭据对象和 PowerShell 会话中的权限。它会凭空变出它的权限吗?无论我做什么,它如何能够写入我的开发环境?我如何让它访问我的其他环境?
我找到了一个有效的修复方法。我可以使用 InteractiveBrowserCredential
而不是 DefaultAzureCredential
.
private SecretClient CreateSecretClient() =>
new(
new Uri($"https://{_keyVaultName}.vault.azure.net/"),
new InteractiveBrowserCredential(),
new SecretClientOptions
{
Retry =
{
Delay = TimeSpan.FromSeconds(2),
MaxDelay = TimeSpan.FromSeconds(16),
MaxRetries = 5,
Mode = RetryMode.Exponential
}
});
我可能还可以使用其他类型的 TokenCredential
,如下所列:https://docs.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet