将 KeyVaultClient 与 MSAL 令牌一起使用 "Unauthorized"
Use KeyVaultClient with MSAL Token "Unauthorized"
桌面应用程序如何使用 Azure AD 读取 KeyVault 机密?
我能够获取 MSAL 令牌,但将其交给 KeyVaultClient 总是会导致:
Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: Operation returned an invalid status code 'Unauthorized'
我什至不确定 KeyVault 是否支持这种令牌,但在我的谷歌搜索中我看到了使用旧版 ADAL 令牌的示例。
我的 KeyVault 具有针对我的 Azure AD 帐户和我所属的组的访问策略。
我从 MSAL 取回的 JWT 令牌的负载具有以下范围:
"scp": "User.Read profile openid email"
这是一个 mcve:
public partial class MainWindow : Window
{
private static string ClientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
public static PublicClientApplication PublicClientApp = new PublicClientApplication(ClientId);
public MainWindow()
{
InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
var secret = await GetKeyVaultSecret("TestSecret");
}
private async Task<string> GetKeyVaultSecret(string secretKey)
{
KeyVaultClient kvClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(AcquireMSALToken));
try
{
var secretBundle =
await kvClient.GetSecretAsync("https://xxxxx.vault.azure.net/",
secretKey, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
return secretBundle.Value;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return null;
}
}
private static async Task<string> AcquireMSALToken(string authority, string resource, string scope)
{
string[] _scopes = new string[] { "user.read" };
AuthenticationResult authResult = null;
var app = PublicClientApp;
var accounts = await app.GetAccountsAsync();
try
{
authResult = await app.AcquireTokenSilentAsync(_scopes, accounts.FirstOrDefault());
return authResult.AccessToken;
}
catch (MsalUiRequiredException)
{
try
{
authResult = await PublicClientApp.AcquireTokenAsync(_scopes);
return authResult.AccessToken;
}
catch (MsalException) { throw; }
}
catch (Exception) { throw; }
}
}
UPDATE
仅供参考,这可行,但我认为这不是基于文档的 AzureServiceTokenProvider 的用途。这让我相信 MSAL 令牌与 KeyVault 不兼容。我的感觉是它只用于 MS Graph 调用。
using Microsoft.Azure.Services.AppAuthentication;
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
var kvClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
var secretBundle = await kvClient.GetSecretAsync("https://xxxxxxxx.vault.azure.net/",
"TestSecret", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
return secretBundle.Value;
访问 Azure 密钥保管库的范围不正确。你应该使用
string[] _scopes = new string[] { "https://vault.azure.net/.default" };
您可以根据需要添加特定权限。
通常您需要完全限定每个范围,但 MS Graph API 是一个特例。它允许您像 {user.read}
.
一样使用 "short form"
您可以按照以下步骤向应用程序授予权限。
1.Click应用注册(预览)->点击您注册的应用。
2.Click API权限->点击添加权限。
3.choose Azure 密钥保管库。
4.click 在 API 权限页面底部授予管理员同意。
桌面应用程序如何使用 Azure AD 读取 KeyVault 机密?
我能够获取 MSAL 令牌,但将其交给 KeyVaultClient 总是会导致:
Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: Operation returned an invalid status code 'Unauthorized'
我什至不确定 KeyVault 是否支持这种令牌,但在我的谷歌搜索中我看到了使用旧版 ADAL 令牌的示例。
我的 KeyVault 具有针对我的 Azure AD 帐户和我所属的组的访问策略。
我从 MSAL 取回的 JWT 令牌的负载具有以下范围:
"scp": "User.Read profile openid email"
这是一个 mcve:
public partial class MainWindow : Window
{
private static string ClientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
public static PublicClientApplication PublicClientApp = new PublicClientApplication(ClientId);
public MainWindow()
{
InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
var secret = await GetKeyVaultSecret("TestSecret");
}
private async Task<string> GetKeyVaultSecret(string secretKey)
{
KeyVaultClient kvClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(AcquireMSALToken));
try
{
var secretBundle =
await kvClient.GetSecretAsync("https://xxxxx.vault.azure.net/",
secretKey, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
return secretBundle.Value;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return null;
}
}
private static async Task<string> AcquireMSALToken(string authority, string resource, string scope)
{
string[] _scopes = new string[] { "user.read" };
AuthenticationResult authResult = null;
var app = PublicClientApp;
var accounts = await app.GetAccountsAsync();
try
{
authResult = await app.AcquireTokenSilentAsync(_scopes, accounts.FirstOrDefault());
return authResult.AccessToken;
}
catch (MsalUiRequiredException)
{
try
{
authResult = await PublicClientApp.AcquireTokenAsync(_scopes);
return authResult.AccessToken;
}
catch (MsalException) { throw; }
}
catch (Exception) { throw; }
}
}
UPDATE
仅供参考,这可行,但我认为这不是基于文档的 AzureServiceTokenProvider 的用途。这让我相信 MSAL 令牌与 KeyVault 不兼容。我的感觉是它只用于 MS Graph 调用。
using Microsoft.Azure.Services.AppAuthentication;
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
var kvClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
var secretBundle = await kvClient.GetSecretAsync("https://xxxxxxxx.vault.azure.net/",
"TestSecret", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
return secretBundle.Value;
访问 Azure 密钥保管库的范围不正确。你应该使用
string[] _scopes = new string[] { "https://vault.azure.net/.default" };
您可以根据需要添加特定权限。
通常您需要完全限定每个范围,但 MS Graph API 是一个特例。它允许您像 {user.read}
.
您可以按照以下步骤向应用程序授予权限。
1.Click应用注册(预览)->点击您注册的应用。
2.Click API权限->点击添加权限。
3.choose Azure 密钥保管库。
4.click 在 API 权限页面底部授予管理员同意。