Retrieve Google Client ID and Client Secret Azure Authentication - azure

I obviously don't want to hard code these values, but I am not sure how to get the stored values in Azure.
This is what I have been doing locally for my app secrets in ASP.NET Core...
app.UseGoogleAuthentication(new GoogleOptions()
{
ClientId = Configuration["Authentication:Google:ClientId"],
ClientSecret = Configuration["Authentication:Google:ClientSecret"]
});

If you are going to host those on Azure WebApps you can use App Settings (they basically are environment variables) to store that data. Take a look here:
https://learn.microsoft.com/en-us/azure/app-service-web/web-sites-configure#application-settings

Related

Azure Key Vault: The user, group, or app does not have secrets set permission on key vault

I am creating a script using Azure CLI that will automatically generate an App Registration (service principal), and then use that App Registration to create a secret that will be stored in Azure Key Vault.
However, I am getting the following error:
The user, group or application 'appid=04b07795-8ddb-461a-bbee-02f9e1bf7b46;oid=0ec2b0e8-daeb-46a8-b627-0d4f61f87157;numgroups=134;iss=https://sts.windows.net/72f988bf-86f1-41af-91ab-2d7cd011db47/' does not have secrets set permission on key vault 'asakeyabcfelaqpgsfnxcy;location=eastus'. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125287
Can anyone provide guidance on what this ID is and how to resolve this error? This is not my App Registration Object ID or App ID.
I think there're 2 points you're now concerning, one is you failed to add secret, another is the app id in the error message is not the one you registered.
I think you've followed the document to execute the cli command, so I just want to explain the second point. Pls allow me show you a code sample for a better explanation.
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
public async Task<IActionResult> PrivacyAsync()
{
var kvUri = "https://your_vault_name.vault.azure.net/";
var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
_ = await client.SetSecretAsync("test0311", "hello");
return View();
}
When we want to add key vault secret to azure, we need to provide a credential so that our operations are authenticated. This is the DefaultAzureCredential() here, and it has several sources to get the authentication like screenshot below.
That means if someone sets the environment variables for authentication, then it will cover the information you entered when executing cli command, this may usually cause the issue that the app is different from what you set. I think you may follow this document to check all your configurations and try again, or you can directly add environment variables with the app you registered on your computer.
By the way, pls don't forget to add access policy in azure portal for the azure ad app you registered.

Retrieve Azure KeyVault secret using client secret

I'm experimenting with various Azure features and currently want to retrieve a secret from KeyVault.
Straight to the case:
I'm using this nuget package to interact with my azure resources.
I've developed a simple .NET Core console app and run it locally.
I have a KeyVault resource with one secret defined which is active and not expired.
I've registered an App in AAD so my locally shipped .NET Core console app has an identity within AAD.
Than I've created a "client secret" within this registered app in AAD to use it to authenticate myself as an app.
After that I've added access policy in my KeyVault resource to allow GET operation for secrets for this registered app:
Then I've developed a small piece of code which should retrieve the desired secret:
public class AzureAuthentication
{
public async Task<string> GetAdminPasswordFromKeyVault()
{
const string clientId = "--my-client-id--";
const string tenantId = "--my-tenant-id--";
const string clientSecret = "--my-client-secret--";
var credentials = new ClientSecretCredential(tenantId, clientId, clientSecret);
var client = new SecretClient(new Uri("https://mykeyvaultresource.vault.azure.net"), credentials);
var secret = await client.GetSecretAsync("admincreds");
return secret.Value.Value;
}
}
However when I'm trying to do this I'm getting an AccessDenied error:
Am I missing something painfully obvious here? Or there is some latency (>30 min for this moment) for which changes from Access policies screen in KeyVault resource are applied?
I test your code and Get permission, it works fine.
From your screenshot, it looks you didn't add the correct service principal related to the AD App to the Access policies.
If you add the service principal related to the AD App, it will appear as APPLICATION, not COMPOUND IDENTITY.
So when you add it, you could search for the client Id(i.e. application Id) or the name of your App Registration directly, make sure you add the correct one.
Make sure your AD App(service principal) has the correct permission in your keyvault -> Access policies

Combine Azure Key Vault with Azure App Configuration

I am pretty new to Azure and I am trying to simulate a real production environment.
So, I've deployed a .netcore 3.1 app to an AppService resource. This web app is able to get the configuration from two other services - KeyVault and App Configuration. I already have configuraed the AppService identity.
I can get the keys from KeyVault using the following code:
var settings = config.Build();
var web = settings["KeyVault:Name"];
var clientId = settings["KeyVault:ClientId"];
var clientSecret = settings["KeyVault:ClientSecret"];
config.AddAzureKeyVault($"https://{web}.vault.azure.net/",
clientId,
clientSecret);
As I can get the keys from the App Configuration:
var settings = config.Build();
config.AddAzureAppConfiguration(settings["AppSettings:Endpoint"]);
And I am able to use them both at the same time through identities and AppConfiguration's key reference
var settings = config.Build();
config.AddAzureAppConfiguration(options =>
{
options
.Connect(settings["AppSettings:Endpoint"])
.ConfigureKeyVault(kv =>
{
kv.SetCredential(new DefaultAzureCredential());
});
});
So, my question is about the code snippet #3: is it safe to store the AppSettings:Endpoint value the appconfig.json in a production environment? To be clear, I am referring to this value:
Moreover, I found here and explanation on how to use the two services together. But first of all, that solution doesn't work for me - I get an Azure.Identity.CredentialUnavailableException: 'ManagedIdentityCredential authentication unavailable, no managed identity endpoint found.'.
On the second hand, he's not clear on where to store the AppSettings:AppConfiguration:Endpoint and AppSettings:Identity:ClientId values, it doesn't answer to my first question then.
Thanks in advance
Short answer - the endpoint https://[your_app_name].azconfig.io is safe to leave anywhere. It does nothing without the other parts that make up the connection string.
Long answer - you can and probably should store the parts that are sensitive, connection strings and their parts, in Key Vault as secrets. If your code needs those values you have options on how to get the values to it. Consider using the web config (it's equivalent as a place that would ordinarily have the secret values but put Key Vault references there instead. Your way works also. Keep in mind that your way may require a code change if your config shifts away from what you've coded.
Be sure that your access policy on KV is using the service principal of your app. I repeat, be sure that your access policy on KV is using the service principal of your app. It will likely only need permissions "list" and "get" for secrets and NOTHING ELSE.
Do not store secrets in your web config or its equivalent. Key Vault is almost free, it's so cheap. I don't deploy apps without them getting their own vault as part of the solution.
Leave comments if this is unclear or needs web references.
You should be able to use Azure Marange Identity to connect to APP Configuration. Use Azure.Identity preview version.
c# Example
https://github.com/nishanperera/Azure-App-Configuration-With-Key-Vault

Is the KeyVaultClient method GetSecret() safe?

I'm working with Azure Key Vault and I'm testing the "Managed Identities" for Azure Resource. Long story short: with this feature we can easily access to a KeyVault secrets from (e.g.) VM, App Service... I wrote this simple code:
private void GetKeyVaultSecrets()
{
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
var akvCallback = new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback);
var keyVaultClient = new KeyVaultClient(akvCallback);
var secret = keyVaultClient.GetSecretAsync("https://mykeyvault.vault.azure.net/secrets/mySecret").GetAwaiter().GetResult();
string superSecret = secret.Value;
}
And I'm able to access my "Secret" without any kind of Authorization. Is it safe? Am I missing something? It looks so strange that with those 7 lines of code you have access to all your secrets. Thanks for your attention.
If you are running this on a service with a system-assigned Managed Identity, here's what actually happens (example for App Service, VM is slightly different):
Your app reads IDENTITY_ENDPOINT and IDENTITY_HEADER environment variables
HTTP call to IDENTITY_ENDPOINT using the IDENTITY_HEADER as authentication
This endpoint cannot be called from the outside, only from within the instance.
Its port is also random
In the call, your app specifies it wants a token for Key Vault (resource https://vault.azure.net)
The Managed Identity endpoint uses the certificate it has created to authenticate to Azure Active Directory with the Client Credentials flow
Azure AD verifies the request and issues a token
Managed Identity endpoint returns the token to your app
KeyVaultClient uses the token to authorize the call to Key Vault
On Virtual Machines, the Instance Metadata Service is used to get tokens.
The main thing to understand is that any process running on the instance itself is capable of getting tokens from the Managed Identity.
Though if you were to get malicious code running on your instance,
other approaches could be in trouble as well :)
If you run that code locally, it can work as well.
AzureServiceTokenProvider also attempts Visual Studio authentication as well as Azure CLI authentication.
So if you are logged in to e.g. AZ CLI, it is able to get an access token for your user to Azure Key Vault and access it.
Reference: https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity?context=azure%2Factive-directory%2Fmanaged-identities-azure-resources%2Fcontext%2Fmsi-context&tabs=dotnet#rest-protocol-examples
Example request done in VMs: https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/tutorial-windows-vm-access-nonaad#access-data

Use Azure Vault Secret from onpremise Web Application

I would like to use an Azure Key Vault secret from an on-premise web application.
I created a Key Vault with a Secret, but in Access Policies I should specify an Authorized Application and in the samples is used an Azure WebApp.
I want instead use the Secret from on-premise MVC web app: shoud i specify nothing and it works ? i specified the Azure Vault and as Principal myself but i'm not sure if this is correct.
Well, something will need to authenticate to access the secret.
Either the current user, or you can use a service principal.
Since we are talking about an MVC app, the service principal is probably easier.
You will need to register a new app in Azure Active Directory via the Azure Portal.
Find Azure AD, and register a new app via App registrations.
The name and URLs don't really matter, but it needs to be of type Web app/API.
The sign-on URL can be https://localhost for example.
Then add a key in the Keys blade to the app (click Settings after the app is created, then Keys).
Copy the client id (application id) and the key somewhere.
Now you can go to your Key Vault, and create a new access policy, and choose the app you created as the principal.
Give it the rights you want, like Secrets -> Get.
Then you can save the policy.
In your app, you can then use the Key Vault library + ADAL like so:
var kvClient = new KeyVaultClient(async (authority, resource, scope) =>
{
var context = new AuthenticationContext(authority);
var credential = new ClientCredential("client-id-here", "key-here");
AuthenticationResult result = await context.AcquireTokenAsync(resource, credential);
return result.AccessToken;
});
SecretBundle secret = await kvClient.GetSecretAsync("https://yourvault.vault.azure.net/", "secret-name");
string secretValue = secret.Value;

Resources