将KeyVaultClient与MSAL令牌“未经授权”一起使用

时间:2019-04-04 14:01:47

标签: c# wpf azure azure-keyvault msal

桌面应用程序如何使用Azure AD读取KeyVault机密?

我能够获取MSAL令牌,但将其交给KeyVaultClient总是会导致:

  

Microsoft.Azure.KeyVault.Models.KeyVaultErrorException:操作返回了无效的状态码“未经授权”

我什至不确定KeyVault是否支持这种令牌,但是在我的Google搜索中,我看到了使用较旧的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; }
    }
}
  

更新

仅供参考,这是可行的,但我认为这不是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;

1 个答案:

答案 0 :(得分:2)

该范围不适用于访问Azure密钥保管库。您应该使用

string[] _scopes = new string[] { "https://vault.azure.net/.default" };

您可以根据需要添加特定的权限。

通常,您需要完全限定每个范围,但是MS Graph API是一种特殊情况。它允许您使用{user.read}之类的“简短格式”。

您可以按照以下步骤为应用程序授予权限。

1。单击“应用程序注册(预览)”->单击您注册的应用程序。

enter image description here

2。单击“ API权限”->单击“添加权限”。

enter image description here

3。选择天蓝色的密钥库。

enter image description here

4。单击“ API权限”页面底部的“授予管理员同意”。

enter image description here