I am saving identity documents via my MVC/Durandal web app to Azure blob storage. I am following this example to encrypt blobs in Azure storage using Azure key vault to store the encryption secret.
Here is my code:
public async Task UploadIdentityDocumentForClient(string fileName, ParsedClientModel parsedClientModel)
{
BlobRequestOptions options = await GetBlobRequestOptions();
await
_storageRepository.CreateEncryptedBlobFromByteArray(_storageManager, _containerName, fileName, parsedClientModel.IdentityDocumentFile, parsedClientModel.IdentityDocumentContentType, options);
return fileName;
}
private static async Task GetBlobRequestOptions()
{
string secretUri = WebConfigurationManager.AppSettings["SecretUri"];
string secretName = WebConfigurationManager.AppSettings["SecretEncryptionName"];
*1 KeyVaultKeyResolver keyVaultKeyResolver = new KeyVaultKeyResolver(GetAccessToken);
*2 IKey rsaKey = keyVaultKeyResolver.ResolveKeyAsync($"{secretUri}/secrets/{secretName}", CancellationToken.None).GetAwaiter().GetResult();
BlobEncryptionPolicy policy = new BlobEncryptionPolicy(rsaKey, null);
BlobRequestOptions options = new BlobRequestOptions
{
EncryptionPolicy = policy
};
return options;
}
public static async Task GetAccessToken(string authority, string resource, string scope)
{
string clientId = WebConfigurationManager.AppSettings["ClientId"];
string clientSecret = WebConfigurationManager.AppSettings["ClientSecret"];
ClientCredential clientCredential = new ClientCredential(clientId, clientSecret);
AuthenticationContext authenticationContext = new AuthenticationContext(authority, TokenCache.DefaultShared);
AuthenticationResult result = await authenticationContext.AcquireTokenAsync(resource, clientCredential);
if (result == null)
{
throw new InvalidOperationException(
"GetAccessToken - Failed to obtain the Active Directory token for application.");
}
*3 return result.AccessToken;
}
public async Task CreateEncryptedBlobFromByteArray(IStorageManager storageManager, string containerName, string fileName,
byte[] byteArray, string contentType, BlobRequestOptions options)
{
CloudBlobContainer container = await CreateStorageContainerIfNotExists(storageManager, containerName);
CloudBlockBlob blob = container.GetBlockBlobReference(fileName);
blob.Properties.ContentType = contentType;
await blob.UploadFromByteArrayAsync(byteArray, 0, byteArray.Length, AccessCondition.GenerateEmptyCondition(), options, new OperationContext());
}
This line...
IKey rsaKey = keyVaultKeyResolver.ResolveKeyAsync($"{secretUri}/secrets/{secretName}", CancellationToken.None).GetAwaiter().GetResult();
always returns null.
I have added breakpoints (*1 to *3) in the code above and have noticed that *2 always gets hit before *3. This means that the KeyVaultKeyResolver(GetAccessToken) call is not waiting for the GetAccessToken call to return with the value.
Any ideas as to what I am doing wrong?
