7

I have this web app which access a keyvault stored in Azure cloud.

To access this KeyVault I use the IConfigurationBuilder Extension

configuration.AddAzureKeyVault(new Uri(KeyvaultUri), new DefaultAzureCredential(true));

I have created an managed identity for all the user who need access to this, meaning they should be able to run the application and have access to the keyvault once they are logged in via SSO, which they currently are forced to do everytime they start the application due to new DefaultAzureCredential(true) What I don't understand is why it everytime need to be requested everytime, and not store the credentials somewhere after it has been entered once, and use that stored credential, can I somehow locally store the required credentials after the initial login?

It is sort of inconvenient to always login when one start their application, and debugging application becomes a bit lengthy with the required login.

Is somehow possible to let the login happen in the background - or somehow store the credentials after first login?

I feel a bit this is getting off tracked - the solution I am seeking should be applicable for those running the solution via a terminal, outside of visual studio. Such as frontend developers - who just need a backend to make reqeuest to a nothing else.

I am not Fat
  • 283
  • 11
  • 36
  • DefaultAzureCredentials is a an ordered pipeline of various ways to authenticate (from doc): EnvironmentCredential, ManagedIdentityCredential, SharedTokenCacheCredential, VisualStudioCredential, VisualStudioCodeCredential, AzureCliCredential, AzurePowerShellCredential, InteractiveBrowserCredential. Just ensure at least one of these succeeds (each one works differently). – Simon Mourier Oct 20 '22 at 17:01
  • @SimonMourier login in via sso is not a problem, the problem is that it required everytime I run the application how do i force it to save the credentials once entered, and reuse them next time the application is set to start. – I am not Fat Oct 20 '22 at 19:48
  • @IamnotFat Hi there, Can't you give an identity to your application instead using the user priviledge to access the key vault? In that case the application will use it's credential to access the Key Vault. So no prompt for login. Which will use client credential flow in OAuth. You could easily achieve this using a Managed Identity. – Dhanuka Jayasinghe Oct 24 '22 at 01:41
  • The simple answer is you "can". There is nothing stopping you from storing anything locally and reading it. The question is, if you want to store locally, then the security of the configuration is not a real concern for you. And if it isn't a concern, don't even bother with Key Vault - Just store whatever in the app settings. i.e. With Key Vault, you get security of credentials, which you don't with app settings. – Ceemah Four Oct 25 '22 at 23:48
  • If I understood your question correctly, if the intention is for debugging purposes only and assuming you are using Visual Studio in Windows OS, you need to choose an account under Azure Service Authentication (Tools -> Options -> Azure Service Authentication). If no user in the option, they need to sign-in first using the account you authorized in keyvault. – jtabuloc Oct 27 '22 at 02:54
  • Why using KV if you can store same thing locally? KV is to keep sensitive information safe and secure. If you are storing it locally, KV is useless. Again, can't you just use application credentials instead of individual credentials? – r2018 Oct 29 '22 at 14:55
  • I feel a bit this is getting off tracked.. – I am not Fat Nov 30 '22 at 03:34

5 Answers5

2

It has no sense to cache the token since it is used only once at startup, what you are looking for is to exclude in your credentials all the wrong ways you are trying to grab the token to connect to your AKV except the one you are really using.

To configure it correcly and do not wait 15 seconds in your startup you should configure DefaultAzureCredentials this way:

        DefaultAzureCredential credentials = new DefaultAzureCredential(new DefaultAzureCredentialOptions
        {
            ExcludeEnvironmentCredential = true,
            ExcludeInteractiveBrowserCredential = true,
            ExcludeAzurePowerShellCredential = true,
            ExcludeSharedTokenCacheCredential = true,
            ExcludeVisualStudioCodeCredential = true,
            ExcludeVisualStudioCredential = true,
            ExcludeAzureCliCredential = true,
            ExcludeManagedIdentityCredential = false,
        });

Exclude all posibilities to grab the token except the one you are using, in this case "Managed Identity" or in other cases AzureCliCredentials.

Regards.

Juanma Feliu
  • 1,298
  • 4
  • 16
0

Can you share a small full code example ? What about using DefaultAzureCredentialOptions. Like:

.ConfigureAppConfiguration((context, config) =>
        {
            var appSettings = config.Build();
            var credentialOptions = new DefaultAzureCredentialOptions();
            var credential = new DefaultAzureCredential(credentialOptions);
            config.AddAzureKeyVault(new Uri(appSettings["Url:KeyVault"]), credential);
        })
Janusz Nowak
  • 2,595
  • 1
  • 17
  • 36
  • I am not sure what sort of code examples your are requesting. I am asking whether it is possible to store the credential after the initial login, so that the developer don't have to reenter their credential everytime they run the application. – I am not Fat Oct 20 '22 at 11:03
  • DefaultAzureCredential support to have option to configure local cache, or you can use specific #if statement that if you are doing local development then you get credential from local file/cert/etc. Was asking about representation example because then it would be faster to provide response. https://learn.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredentialoptions.excludesharedtokencachecredential?view=azure-dotnet – Janusz Nowak Oct 20 '22 at 12:19
0

I assume you've got different Azure subs for non-prod and prod (that contain a non-prod and prod key vault instances).

In the non-prod key vault instance, create a new role assignment with the required members i.e. the developer AAD accounts. enter image description here

Given you're using DefaultAzureCredential, these members will be able to leverage Azure service authentication in Visual Studio or Visual Studio Code (or EnvironmentCredential) as DefaultAzureCredential will cycle through these various credential types including VisualStudioCredential and VisualStudioCodeCredential (and EnvironmentCredential) respectively.

Developers can authenticate in their IDE e.g. in Visual Studio by going to Tools > Options > Azure Service Authentication where they can authenticate using their Azure credentials. enter image description here

Assuming their AAD accounts have been granted access to the (non-prod) key vault instance, they will be able to get access.

The deployed application - presumably running in Azure - would use a different credential type e.g. ManagedIdentityCredential or EnvironmentCredential. Given these are also handled by the DefaultAzureCredential, no code changes would be required for this to work for the deployed instance of your app.

The only difference with the prod key vault instance is that you probably wouldn't create role assignments for the developer accounts.

the solution I am seeking should be applicable for those running the solution via a terminal, outside of visual studio. Such as frontend developers - who just need a backend to make reqeuest to a nothing else.

For these type of users that just want to run the app from the terminal, they could set some environment variables that will get picked up by the EnvironmentCredential (which is another one of the credential types included in the DefaultAzureCredential) e.g. if they're running the app in docker they could specify AZURE_USERNAME and AZURE_PASSWORD environment vars (or alternatively AZURE_CLIENT_ID and AZURE_CLIENT_SECRET for more of a 'machine' context) e.g. docker run -e AZURE_USERNAME=username -e AZURE_PASSWORD=password ...

Ryan.Bartsch
  • 3,698
  • 1
  • 26
  • 52
0

Based upon your question, I am assuming the following:

  • The web application has a managed identity and has permissions to your key vault.
  • The users are logging in as themselves in the front end of the web application.

The new DefaultAzureCredential(true) just grabs the users current credentials. This will be the front end user. These are cached automatically based upon your organization's security policy. I assume this is working correctly.

The login frequency is out of your control as a developer. The issue you are having is in the organizational settings in Azure Active Directory. Your sign in frequency may be set to one of these:

Require reauthentication every time

Sign-in frequency control every time risky user

To fix your issue, set the sign-in frequency to be less than that and you should be good. (I don't have access to this or I would post better pictures)

conditional-access-policy-session-sign-in-frequency.png

Here is the link to the full article on how to do this:

Configure authentication session management with Conditional Access

Lucky Lindy
  • 133
  • 8
  • Interesting approach, I see that the azure cli credential provider generates a token which is valid for 90 days - is it somehow possible to modify the the lifespan of the token provided by the InteractiveBrowserCredential? – I am not Fat Jan 02 '23 at 13:58
  • I think [this](https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-configurable-token-lifetimes#configurable-token-lifetime-properties) describes how to do that. I re-read your question and had a question. Are all users using the managed identity to log in? If so, have you tried using their individual accounts? I don't think the credentials for the managed identity will ever be cached if they are running under a different identity. – Lucky Lindy Jan 04 '23 at 16:50
  • yes - I mistaken mentioned it as managed identity, when what they actually used their individual account to login. – I am not Fat Jan 06 '23 at 10:34
0

This was what I was looking for

https://github.com/Azure/azure-sdk-for-net/issues/23896

A silent authentication step that stores the credentials first time it is entered into a cache file and then reuses it when rerunning the application the second time without prompting the user to enter credentials.

Thus ensuring credentials arent stored in git, and cache file stored locally on each developers local machine.

I am not Fat
  • 283
  • 11
  • 36
  • Since you are using an individual users login, I would suggest that you go with the first part of @Ryan.Bartsch solution and use IAM. Depending on your password reset policy, this may bite you and create more work for you in the future. It is also more secure and will abide with your companies security policy, which might include 2 factor authentication. But you might have a specific use case, so I will leave the final decision up to you. – Lucky Lindy Jan 09 '23 at 18:27