using Azure.Security.KeyVault.Secrets;
using Azure.Identity;
using Azure;
using System.Threading;
using System.Linq;
// Ref: https://www.serverlessnotes.com/docs/no-code-integration-of-azure-key-vault-with-azure-functions
namespace App1
{
public class GetKeyVault
{
[FunctionName("GetKeyVault")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("Function execution started.");
// Get KV Url from AppConfig
var KvUrl = Environment.GetEnvironmentVariable("KvUrl");
log.LogInformation($"Kv Url : {KvUrl}");
string allowedDomains = Environment.GetEnvironmentVariable("allowedDomains");
log.LogInformation($"allowedDomains : {allowedDomains}");
if (!string.IsNullOrWhiteSpace(allowedDomains))
{
string[] allowedDomainList = allowedDomains.Split(',');
// Check if the domain is allowed
var clientOrigin = GetOroginFromRequestHeaders(req);
if (!string.IsNullOrWhiteSpace(clientOrigin) && allowedDomainList.Contains(clientOrigin))
{
log.LogInformation($"clientOrigin : {clientOrigin}");
var resultAll = await GetAllSecretAsync(KvUrl);
List<KeyVaultResponse> kvList = KvResponseMapper(resultAll);
return new OkObjectResult(kvList);
}
else
{
log.LogInformation($"clientOrigin : {clientOrigin}");
return new UnauthorizedResult();
}
}
else
{
log.LogInformation($"There is no allowedDomains set in your functionApp.");
return new BadRequestResult();
}
}
#region Private Section
/// <summary>
/// Get All keyVault Secret in single call
/// </summary>
/// <param name="kvUrl"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<IList<KeyVaultSecret>> GetAllSecretAsync(string kvUrl, CancellationToken cancellationToken = default)
{
var _client = new SecretClient(new Uri(kvUrl), new DefaultAzureCredential());
AsyncPageable<SecretProperties> secretProperties = _client.GetPropertiesOfSecretsAsync(cancellationToken);
var secrets = new List<KeyVaultSecret>();
await foreach (var secretProperty in secretProperties)
{
var response = await _client.GetSecretAsync(secretProperty.Name, cancellationToken: cancellationToken).ConfigureAwait(false);
secrets.Add(response.Value);
}
return secrets;
}
/// <summary>
/// Key Vault Response Mapper
/// </summary>
/// <param name="resultAll"></param>
/// <returns></returns>
private List<KeyVaultResponse> KvResponseMapper(IList<KeyVaultSecret> resultAll)
{
var kvList = new List<KeyVaultResponse>();
foreach (var kv in resultAll)
{
KeyVaultResponse res = new()
{
Name = kv.Name,
Value = kv.Value
};
kvList.Add(res);
}
return kvList;
}
/// <summary>
/// Get Client Origin that requested the function
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
private static string GetOroginFromRequestHeaders(HttpRequest request)
{
var clientIp = request.Headers["Origin"].ToString();
if (!string.IsNullOrEmpty(clientIp))
{
return clientIp;
}
return "";
}
#endregion
}
}