Reputation: 2583
I have to use the REST API with .Net framework 4 and 4.5. My applications are hosted both in Azure ( as app service) and on Azure VM.
I know there Azure has a concept of managed identity. However, I'm trying to implement fetching secrets from Azure Key vault using REST API. The applications are using .Net framework 4 and 4.5.
The code is as below:
string keyVaultUrl = "https://KeyVault.vault.azure.net";
string secretName = "Test";
string tenantId = "tenantId";
string clientId = "clientId";
string clientSecret = "clientSecret Vaule ";
I'm getting a access token by calling a custom method as below:
string accessToken = await GetAccessToken(tenantId, clientId, clientSecret);
The above code works fine.
For me, it's like fetching one secret from the Key vault by exposing another secret.
I have seen lots of post says using "managed identity". As I said earlier, I have to use the REST API with .Net framework 4 and 4.5. My applications are hosted both in Azure ( as app service) and on Azure VM. I believe in this case "managed identity" is not applicable - specifically when it comes to REST and .Net 4/.net 4.5 and when application does not supports required Key vault and Entra ID related namespace ( e.g. key vault "Microsoft.Azure.KeyVault" namespace.)
My question is what is the best ways to store "clientSecret" as its getting used to fetch the secrets from Key vault ? Where can I store the client "clientSecret" and use in the code?
Upvotes: 0
Views: 198
Reputation: 16064
Note that: ClientID is mandatory to generate access token, if you do not want to make use of client secret then you can generate access token using Interactive flow or Username/Password flow.
For an application to make it as Public you need to set Allow public client flows as YES:
But according to Microsoft Username/Password flow is not recommended due to security issues.
class Program
{
private const string TenantId = "your-tenant-id";
private const string ClientId = "your-client-id";
private const string Resource = "https://vault.azure.net";
static async Task Main(string[] args)
{
string username = "[email protected]";
string password = "yourpassword";
try
{
var app = PublicClientApplicationBuilder.Create(ClientId)
.WithTenantId(TenantId)
.Build();
var securePassword = new System.Security.SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
var result = await app.AcquireTokenByUsernamePassword(
new[] { $"{Resource}/.default" },
username,
securePassword)
.ExecuteAsync();
Console.WriteLine("Access Token: " + result.AccessToken);
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
}
You can also make use of InteractiveBrowserCredential flow which do not need client secret:
class Program
{
private const string ClientId = "ClientID";
private const string TenantId = "TenantID";
private const string Resource = "https://vault.azure.net";
static async Task Main(string[] args)
{
var credential = new InteractiveBrowserCredential(new InteractiveBrowserCredentialOptions
{
ClientId = ClientId,
TenantId = TenantId
});
var tokenRequestContext = new TokenRequestContext(new[] { $"{Resource}/.default" });
var token = await credential.GetTokenAsync(tokenRequestContext);
Console.WriteLine("Access Token: " + token.Token);
}
}
If the above does not resolve the issue, then you have to Store the clientSecret
in environment variables. This is a simple method and keeps sensitive data out of your codebase as suggested by Provadis.
string clientSecret = Environment.GetEnvironmentVariable("YourClientSecretEnvironmentVariable");
clientSecret
before using it to obtain the access token.string clientSecret = await GetSecretFromKeyVault(keyVaultUrl, "YourClientSecretName");
string accessToken = await GetAccessToken(tenantId, clientId, clientSecret);
Upvotes: 1
Reputation: 13
As far as i know, the common method is to store secrets, such as the secret to access the key vault, in environment variables and then accessing the env-vars through your code.
Is this helpfull?
Upvotes: 1