UWP/WinUI桌面应用程序如何访问Azure Key Vault秘钥?

5

微软提供了几种获取 Azure Key Vault 密钥的安全访问方式,特别是使用托管标识或服务主体作为身份提供者。然而,这些方法明确设计为与基于 Azure 的资源(如 Web 应用程序和微服务)配合使用。它们不适用于 UWP/WinUI 桌面应用程序。

到目前为止,我发现允许 UWP/WinUI 桌面应用程序访问 Key Vault 的唯一方法是将应用程序的 Azure 注册信息(TenentId、ClientId 和 ClientSecret - 本身就是秘密!)加载到环境变量中,当创建新的 SecretClient 对象(Azure.Security.KeyVault.Secrets)时,这些信息会被 DefaultAzureCredential() 方法捕获。

但这意味着我需要将这些秘密存储在代码或配置文件中以在运行时读取。绝对不是最佳实践!我一定缺少什么。

2020 年在 UWP/WinUI 桌面应用程序中安全地访问 Key Vault 密钥的最佳实践是什么 - 而不会同时泄露其他秘密?


最常见的方法是强制客户端使用AAD进行身份验证,然后以此方式访问KV。 - MichaelHoward-MSFT
1
@MichaelHoward-MSFT,您是否建议用户通过AAD登录,然后使用他们的凭据信息以及应用程序的客户端ID来访问Key Vault?如果是这样,在用户所在的租户与应用程序所在的租户(Key Vault所在的地方)不同的多租户情况下,这是否有效? - FactoryOptimizr
2个回答

1
在一天结束时,您的应用程序必须存储某种秘密 - 因为它需要向您的密钥保管库实例提供该秘密,以证明该应用程序确实被允许访问存储在该保管库中的秘密。这类似于从数据库检索值 - 您必须在获取值之前存储并提供连接字符串。
如果不知道您打算如何部署应用程序的特定用例,则无法建议您应该或不应该做什么。在我们的情况下,我们有一个 WinForms 应用程序,由我们的支持团队明确安装到我们客户的机器上,这意味着我们一直在使用旧的、黄金标准客户端证书,直到现在 - 当然还有自定义验证步骤。
值得庆幸的是,Key Vault 明确支持客户端证书(以下步骤来自链接的 MSDN):
  1. 创建一个PKCS#12归档(.pfx)证书。创建证书的选项包括Windows上的MakeCert和OpenSSL。
  2. 将证书安装到当前用户的个人证书存储中。将密钥标记为可导出是可选的。请注意证书的Thumbprint,稍后在此过程中会用到。
  3. 将PKCS#12归档(.pfx)证书导出为DER编码的证书(.cer)。
  4. 在Azure AD中注册应用程序(App registrations)。
  5. 上传DER编码的证书(.cer)到Azure AD:
    a. 在Azure AD中选择应用程序。
    b. 导航到“Certificates & secrets”。
    c. 选择“Upload certificate”以上传包含公钥的证书。.cer、.pem或.crt证书均可接受。
  6. 将密钥保管库名称、应用程序ID和证书Thumbprint存储在应用程序的appsettings.json文件中。
  7. 导航到Azure门户中的Key vaults。
  8. 选择在“生产环境中使用Azure Key Vault”部分中创建的密钥保管库。
  9. 选择“访问策略”。
  10. 选择“添加访问策略”。
  11. 打开“秘密权限”,并为应用程序提供获取和列出权限。
  12. 选择“选择主体”,并按名称选择已注册的应用程序。选择“选择”按钮。
  13. 选择“确定”。
  14. 选择“保存”。
  15. 部署应用程序。
我们目前正在使用Key Vault替换我们的自定义客户端证书验证器,因为这将使一切变得更加容易 - 在Azure门户内管理证书和吊销,而不是使用我们的自定义管理应用程序。

除非您使用 Azure.Security.KeyVault.Secrets 类中的 GetSecret,否则无法在 UWP 应用程序中使用客户端证书,因为它被拒绝。这在移动设备(和 UWP)以及 Mac 应用程序中不起作用(错误提示如此)。 - Guy Lowe

-1
我需要将这些秘密信息存储在代码或配置文件中,在运行时读取。
您可以将 Azure 注册信息(TenentId、ClientId 和 ClientSecret)设置到 Secret 管理器中,并读取该值,而不是暴露这些秘密信息。
请参考以下步骤:
1. 启用安全管理器。您需要使用 init 关键字,在项目目录下运行
dotnet user-secrets init

这将在项目.csproj文件中为UserSecretId创建Guid。

enter image description here

2.设置密钥。您可以使用 set 关键字来设置密钥

dotnet user-secrets set tenantId "xxxxxxxxxxxx"

enter image description here

3. 在代码中从密钥管理器中读取。

private readonly IConfiguration _configuration;

public WeatherForecastController( IConfiguration configuration)
{
    _configuration = configuration;
}
string keyVaultUrl = "https://xxxx.vault.azure.net";
TokenCredential credential = new DefaultAzureCredential();
credential = new ClientSecretCredential(_configuration["tenantId"], _configuration["clientId"], _configuration["clientSecret"]);

var secretClient = new SecretClient(new Uri(keyVaultUrl), credential);
KeyVaultSecret secret = secretClient.GetSecret("xxxx");
var secretvalue = secret.Value;

工作输出如下:

enter image description here

关于秘密管理器的更多细节,您可以参考这个文章


1
感谢关于Secrets Manager的信息,@Joey Cai。然而,它只能在本地工作。它非常适合开发,但无法用于从商店部署的桌面应用程序。 - FactoryOptimizr
不,看起来在商店的桌面应用中,你必须在 appsetting.json 文件中显示 tenantid。 - Joey Cai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接