0
votes

I have been battling with using Azure Key Vault in both development and production versions of my app for several days now. I can't seem to set things up correctly to gain access to my key vault from my app running locally during debug in VS 2017 or when deployed as a Web App on Azure. When I use the CLI with my account and resource group set I have no problem accessing a secret in my vault. However, when I try to access the same secret using the code below in my app I get an error stating that the access token was not obtained (paraphrased).

Imports System.Threading.Tasks
Imports Microsoft.Azure.KeyVault
Imports Microsoft.Azure.KeyVault.Models
Imports Microsoft.Azure.Services.AppAuthentication
Imports Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider

Public Class SocialXXXXXXX
    Inherits System.Web.UI.Page

    Public Property Message As String

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        'Message = "Your application description page."
        Dim retries As Integer = 0
        Dim retry As Boolean = False

        Try
            Dim azureServiceTokenProvider As AzureServiceTokenProvider = New AzureServiceTokenProvider()

            Dim keyVaultClient As KeyVaultClient = New KeyVaultClient(New KeyVaultClient.AuthenticationCallback(AddressOf GetAccessTokenAsync))
            Dim secret = keyVaultClient.GetSecretAsync("https://XXXXXXXvault.vault.azure.net/secrets/ExamplePassword/52ec77ddc2dXXXXXXX6c63f6c9").Result
            TextBox7.Text = secret.Value
        Catch keyVaultException As KeyVaultErrorException
            TextBox7.Text = keyVaultException.Message
        End Try



    End Sub

    Private Shared Function getWaitTime(ByVal retryCount As Integer) As Long
        Dim waitTime As Long = (CLng(Math.Pow(2, retryCount)) * 100L)
        Return waitTime
    End Function

    Public Async Function GetAccessTokenAsync() As Task(Of String)
        Dim azureServiceTokenProvider = New AzureServiceTokenProvider()
        Dim accessToken As String = Await azureServiceTokenProvider.GetAccessTokenAsync("https://XXXXXXXvault.vault.azure.net/")
        Return accessToken
    End Function

I would like to be able to access my secrets during development and production.

Update: Another user over at https://forums.asp.net/p/2158070/6271824.aspx?p=True&t=636995498339724660 suggested a similar approach as @Joyey Cai below. However, I am reluctant to go that route as instead of using MSI, it requires me to include my app secret either in my code or in a setting. I have gone through your many tutorials and even deleted everything other than my web app from Azure and started over following MS's tutorial at https://docs.microsoft.com/en-us/learn/modules/manage-secrets-with-azure-key-vault/1-introduction and followed microsoft's recommendations verbatim (twice actually) and still have had not luck. I have also found that others are having the same issue and thus far I have not found that anyone has solved it. The problem appears to reside in the fact that Microsoft.Azure.Services.AppAuthentication is not authenticating the account which the developer is using for Azure Service Authentication (Tools>Azure>Azure Service Authentication in VS). I am also unsure if something else may be wrong with Microsoft.Azure.Services.AppAuthentication since not only will my app not get the secret when debugging locally but it also does not get the secret when deployed on the same machine that the key vault resides on. This is a very perplexing problem.

1
What about this answer ? it would be the normal approach using vs 2017Thomas
It appears that this may actually be related to a problem with VS. See developercommunity.visualstudio.com/content/problem/335906/…. I am still working on this.Jamie

1 Answers

0
votes

You could use the code as below and add permission to your application.

Imports Microsoft.Azure.KeyVault
Imports Microsoft.IdentityModel.Clients.ActiveDirectory

Public Class Class1
    Shared appId As String = "xxxxxxxxxxxxxxx"
    Shared appSecret As String = "xxxxxxxxxxxxxxx"
    Shared tenantId As String = "xxxxxxxxxxxxxxx"

    Public Shared Sub Main()
        Dim kv = New KeyVaultClient(AddressOf GetAccessToken)
        Dim scret = kv.GetSecretAsync("https://yourkeyvaultname.vault.azure.net", "yoursecretname").GetAwaiter().GetResult().Value
    End Sub

    Public Shared Async Function GetAccessToken(ByVal azureTenantId As String, ByVal clientId As String, ByVal redirectUri As String) As Task(Of String)
        Dim context = New AuthenticationContext("https://login.windows.net/" & tenantId)
        Dim credential = New ClientCredential(appId, appSecret)
        Dim tokenResult = Await context.AcquireTokenAsync("https://vault.azure.net", credential)
        Return tokenResult.AccessToken
    End Function
End Class

Also, you need to add permission with "Key Vault" to the registered app. enter image description here

In Key vault channel, you need to Add policies to your registered application or user. And in Access Control you need to add permission to your registered application or user. enter image description here enter image description here

The result:

enter image description here

Here is the C# code sample you can refer to.