Reputation: 2583
I'm trying to fetch the secrets from the Azure key vault from .Net console application using REST API. Below is the code I'm trying to use for this from net.
Below way I'm trying to get access token and secret value:
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
namespace KeyVaultSecretFetcher
{
class Program
{
static async Task Main(string[] args)
{
// Replace with your Key Vault URL, secret name, and authentication token
string keyVaultUrl = "https://KeyVault.vault.azure.net";
string secretName = "Test3";
//string accessToken = "<your-access-token>";
string tenantId = "tenantId"; // Your tenant ID
string clientId = "clientId"; // Your application (client) ID
string clientSecret = "clientSecret Vaule "; // Your client secret
string accessToken = await GetAccessToken(tenantId, clientId, clientSecret);
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
string
secretUrl = $"{keyVaultUrl}/secrets/{secretName}?api-version=7.3";
HttpResponseMessage response = await client.GetAsync(secretUrl);
if (response.IsSuccessStatusCode)
{
string responseBody = await response.Content.ReadAsStringAsync();
var secret = System.Text.Json.JsonSerializer.Deserialize<Secret>(responseBody);
Console.WriteLine("Secret value: " + secret.Value);
}
else
{
Console.WriteLine("Error fetching secret: " + response.StatusCode);
}
}
private static async Task<string> GetAccessToken(string tenantId, string clientId, string clientSecret)
{
using (var client = new HttpClient())
{
var body = new StringContent($"grant_type=client_credentials&client_id={clientId}&client_secret={clientSecret}&resource=https://vault.azure.net", Encoding.UTF8, "application/x-www-form-urlencoded");
var response = await client.PostAsync($"https://login.microsoftonline.com/{tenantId}/oauth2/token", body);
response.EnsureSuccessStatusCode();
var jsonResponse = await response.Content.ReadAsStringAsync();
dynamic tokenResponse = JsonConvert.DeserializeObject(jsonResponse);
return tokenResponse.access_token;
}
}
class Secret
{
public string Value { get; set; }
}
}
}
However, I'm unable to fetch the secret value. Is there anything wrong in the code or settings?
This is how API permission is given:
and, app permission is disabled somehow (not sure why). So I have given delegated permission as below:
How to get the secret value? I need to achieve this via REST API only.
Upvotes: 0
Views: 128
Reputation: 22552
I have one key vault named srikv2810
with access configured as Azure RBAC as below:
Now I created one secret named secret01
in above key vault with value as:
To get this secret value via REST API with token generated using service principal, make sure to add "Key Vault Secrets User" role to application under key vault.
Initially, I registered one application and granted same API permissions as below:
Now, I added "Key Vault Secrets User" role to above app registration under key vault like this:
When I ran your code in my environment to get secret value, I too got blank results:
To resolve this, make use of below modified code where I got secret content successfully in response:
using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json.Serialization;
namespace KeyVaultSecretFetcher
{
class Program
{
static async Task Main(string[] args)
{
string keyVaultUrl = "https://kvname.vault.azure.net";
string secretName = "secret1";
string tenantId = "tenantId";
string clientId = "appId";
string clientSecret = "secret";
string accessToken = await GetAccessToken(tenantId, clientId, clientSecret);
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
string secretUrl = $"{keyVaultUrl}/secrets/{secretName}?api-version=7.3";
HttpResponseMessage response = await client.GetAsync(secretUrl);
string responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
try
{
var secret = System.Text.Json.JsonSerializer.Deserialize<Secret>(responseBody);
Console.WriteLine("Secret value: " + secret?.Value);
}
catch (Exception ex)
{
Console.WriteLine("Error deserializing secret value: " + ex.Message);
}
}
else
{
Console.WriteLine($"Error fetching secret: {response.StatusCode}");
}
}
private static async Task<string> GetAccessToken(string tenantId, string clientId, string clientSecret)
{
using (var client = new HttpClient())
{
var body = new StringContent($"grant_type=client_credentials&client_id={clientId}&client_secret={clientSecret}&resource=https://vault.azure.net", Encoding.UTF8, "application/x-www-form-urlencoded");
var response = await client.PostAsync($"https://login.microsoftonline.com/{tenantId}/oauth2/token", body);
response.EnsureSuccessStatusCode();
var jsonResponse = await response.Content.ReadAsStringAsync();
dynamic tokenResponse = JsonConvert.DeserializeObject(jsonResponse);
return tokenResponse.access_token;
}
}
class Secret
{
[JsonPropertyName("value")]
public string Value { get; set; }
}
}
}
Response:
Upvotes: 1