使用密钥库中的证书访问其他租户中的多租户应用程序

Use a certificate in the keyvault to access multi-tenant application in other tenant

我们的 Azure AD 租户中有一个多租户应用程序。它在其他一些租户(我们知道哪些租户)中获得授权。并且它注册了多个证书以用作客户端凭据。

我们想从本地存储中删除证书,并使用密钥保管库中的证书为其中一个外部租户请求令牌。根据 documentation 这是用例之一。

我们的租客(id: xxxx):

其他租户(id: yyyy):

问题 1:

如何在连接到现有应用程序(应用程序 ID:abcd-xxx-xxxx-xxx)的密钥保管库中创建证书?请务必注意,由于该应用程序已获得多个第三方管理员的批准,因此无法重新创建。在证书过期后创建新证书的次数相同。

问题 2:

如何将 Microsoft.Azure.Services.AppAuthentication 库设置为:

  1. 使用托管标识访问我们租户 (xxxx) 中的密钥保管库。
  2. 使用密钥库中的证书在其他公司租户 (yyyy) 中为我们的应用程序 (abcd-xxx-xxxx-xxx) 请求令牌

答案一:

您可以使用如下所示的 az ad sp credential reset 命令。如果您不想覆盖App已有的证书,请传入--append参数。

az ad sp credential reset --name '<application-id>' --keyvault joykeyvault --cert cer136 --create-cert --append

答案2:

1.To 使用 MSI 访问租户中的 keyvault,只需使用下面的代码。

无需更改代码,当您 运行 您在 Azure 应用服务或启用了托管标识的 Azure VM 上的代码时,库会自动使用托管标识,请参阅此 link .

环境变量 AzureServicesAuthConnectionString 必须设置为可以访问密钥库的任何 credentialRunAs=Developer; DeveloperTool=AzureCli for dev 或 RunAs=App; for managed service identity (automatically in azure).

using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Azure.KeyVault;

// Instantiate a new KeyVaultClient object, with an access token to Key Vault
var azureServiceTokenProvider1 = new AzureServiceTokenProvider();
var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider1.KeyVaultTokenCallback));

2.If 你想使用服务主体及其存储在密钥库中的证书来获取另一个租户中资源的令牌,AzureServiceTokenProvider 上的连接字符串必须设置为 RunAs=App;AppId={TestAppId};KeyVaultCertificateSecretIdentifier={KeyVaultCertificateSecretIdentifier} 然后你可以为其他租户获得代币。

const string appWithCertConnection = "RunAs=App;AppId={TestAppId};KeyVaultCertificateSecretIdentifier=https://myKeyVault.vault.azure.net/secrets/myCert";

然后使用代码获取令牌,例如对于资源 https://management.azure.com/.

var azureServiceTokenProvider2 = new AzureServiceTokenProvider(appWithCertConnection);
string accessToken = await azureServiceTokenProvider2.GetAccessTokenAsync("https://management.azure.com/", "tenant-id-of-thridh-party-tenant").ConfigureAwait(false);