Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE REQ] Azure.Identity: Access Token Caching #18938

Closed
poyadav2001 opened this issue Feb 23, 2021 · 18 comments
Closed

[FEATURE REQ] Azure.Identity: Access Token Caching #18938

poyadav2001 opened this issue Feb 23, 2021 · 18 comments
Assignees
Labels
Azure.Identity Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. feature-request This issue requires a new behavior in the product in order be resolved.
Milestone

Comments

@poyadav2001
Copy link

Library or service name.
What library or service is this request related to? [e.g. Azure.Storage.Blobs]
Azure.Identity

Is your feature request related to a problem? Please describe.
What feature would you like to get added? What problem is it solving?

We wanted to directly use managed identity to get an access token and use it for authentication in service to service calls.
The current recommendation is to use the MSAL library which uses an app registration to get the access token.
With app registration, we need to securely generate, renew and secure the credentials (a secret or cert) and then use the credentials in our application code for authenticating to the app registration.
We could use the managed identity directly for getting the access token without having to worry about credentials by
var managedIdentityCredential = new ManagedIdentityCredential(ManagedIdentityClientId); string token = (await managedIdentityCredential.GetTokenAsync(new TokenRequestContext(new[] { scope})).ConfigureAwait(false)).Token;

But the issue is that with Managed Identity credentials, the token caching and refresh has to be handled by the caller. The logic for token resiliency, which is inbuilt in MSAL has to be implemented by the caller.
MSAL offers benefit of token resiliency, refreshing the token much earlier than its expiry, but using the old token in case of Aad outage providing guaranteed downtime in case of AAD outage.
Taken together, implementing all this at the level of caller is too much work, generating greater scope for error and might require frequent changes to this logic in case the lifetimes or properties on the token change.

Will caching, refresh and resiliency be supported in future versions of Azure.Idenitity so that Manged Identity can be used directly for service to service calls?
Please let me know if such a functionality already exists and I am missing something

@ghost ghost added needs-triage Workflow: This is a new issue that needs to be triaged to the appropriate team. customer-reported Issues that are reported by GitHub users external to the Azure organization. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that labels Feb 23, 2021
@jsquire jsquire changed the title [FEATURE REQ] [QUERY] Azure.Identity: Access Token Caching Feb 23, 2021
@jsquire jsquire added Azure.Identity Client This issue points to a problem in the data-plane of the library. needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team labels Feb 23, 2021
@ghost ghost removed the needs-triage Workflow: This is a new issue that needs to be triaged to the appropriate team. label Feb 23, 2021
@jsquire
Copy link
Member

jsquire commented Feb 23, 2021

Thank you for your feedback. Tagging and routing to the team member best able to assist.

@christothes
Copy link
Member

Hi @poyadav2001 - If you are using the Azure.Storage.Blobs client, the authorization policy it uses (BearerTokenAuthenticationPolicy) automatically manages token lifetime and background refresh. Using that in combination with ManagedIdentityCredential or DefaultAzureCredential, which combines various credentials together so that auth works seamlessly both when your application is deployed or in local development, should handle it all for you.

If you prefer to manage token lifetimes directly and make REST calls directly to an Azure service without the convenience of the client SDK, you will need to handle refreshes by calling the GetTokenAsync method on your preferred Credential type.

Do you have a scenario where the built in token management of Azure.Storage.Blobs doesn't provide what you need?

@christothes christothes added the needs-author-feedback Workflow: More information is needed from author to address the issue. label Feb 23, 2021
@ghost ghost removed the needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team label Feb 23, 2021
@poyadav2001
Copy link
Author

poyadav2001 commented Feb 23, 2021

We want to call a protected API with an Aad Bearer token as the authorization header in the request, something that can be achieved through MSAL, but MSAL uses app registration and we wanted to use managed identities instead.
The code with MSAL
IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(this.clientId)
.WithAuthority(AzureCloudInstance.AzurePublic, this.tenantId)
.WithClientSecret(clientSecret)
.Build();
result = await app.AcquireTokenForClient(new[] { this.scope }).ExecuteAsync();
this.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", resullt.AccessToken);
Do we have a similar client in Azure Identity that can get access token using Managed identity and manage token refresh, caching and resilience?

@ghost ghost added needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team and removed needs-author-feedback Workflow: More information is needed from author to address the issue. labels Feb 23, 2021
@christothes
Copy link
Member

Currently we don't expose any cache or refresh management mechanism in the credentials. Some credentials do cache internally where possible, but this is an implementation detail that is not exposed as it's subject to change.

However, BearerTokenAuthenticationPolicy is an example of how tokens can be cached and refreshed.

@poyadav2001
Copy link
Author

poyadav2001 commented Feb 23, 2021

Thank you Christopher for the information. As it is recommended that we use MSAL for service to service calls, and the added functionality it offers, we will use that at the moment.
This was originally a feature request, I am suggesting a client in Azure Identity similar to MSAL so that we can get access tokens to call protected APIs. This will eliminate the need for credentials which need to be maintained in the case of MSAL and we can get token directly from managed identity endpoint
The Azure storage blob client or Secret client are for accessing azure storage or Azure Key vault. I was requesting a client to make calls to protected APIs or or other Azure app services

@poyadav2001 poyadav2001 changed the title [QUERY] Azure.Identity: Access Token Caching [FEATURE REQ] Azure.Identity: Access Token Caching Feb 24, 2021
@christothes christothes removed the needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team label Feb 24, 2021
@christothes christothes added the feature-request This issue requires a new behavior in the product in order be resolved. label Mar 9, 2021
@ghost ghost added the needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team label Mar 9, 2021
@christothes christothes removed the question The issue doesn't require a change to the product in order to be resolved. Most issues start as that label Mar 9, 2021
@jsquire jsquire added this to the Backlog milestone Mar 22, 2021
@christothes
Copy link
Member

The 1.4.0-beta.5 release of Azure.Identity includes options to specify TokenCachePersistenceOptions to control how the token cache is persisted and shared across credentials. I believe that would enable your scenario.

@christothes christothes added the needs-author-feedback Workflow: More information is needed from author to address the issue. label Apr 6, 2021
@ghost ghost removed the needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team label Apr 6, 2021
@ghost ghost added the no-recent-activity There has been no recent activity on this issue. label Apr 13, 2021
@ghost
Copy link

ghost commented Apr 13, 2021

Hi, we're sending this friendly reminder because we haven't heard back from you in 7 days. We need more information about this issue to help address it. Please be sure to give us your input. If we don't hear back from you within 14 days of this comment the issue will be automatically closed. Thank you!

@poyadav2001
Copy link
Author

I think the TokenCachePersistenceOptions is not what we are looking for. We wanted resiliency, say a token is valid for 24 hours, it is refreshed every 12 hours, but if the refresh fails, we continue to use the old token till it expires. In the case when Aad is down, this buys us a minimum of 12 hours downtime as any token we have would be valid for at least the next 12 hours.

We are using managed identity to get an access token for service to service calls.
We use the ManagedIdentityCredentials class in Azure.Identity and directly call the GetTokenAsync method to get an access token. We then add this token as a bearer token to our request header while calling other services. The partner services extract this token from the header, and validate it and check that the calling service is in their whitelist.

This is how we are utilizing the Azure Identity library, and we have had to implement caching as well as resiliency on our own.. Let us know if we are missing something or if there is a simpler way to do this.

@ghost ghost added needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team and removed needs-author-feedback Workflow: More information is needed from author to address the issue. no-recent-activity There has been no recent activity on this issue. labels Apr 16, 2021
@christothes
Copy link
Member

@poyadav2001 Yes, you are correct that the ManagedIdentityCredential is not one that currently caches on your behalf. In this case, if you need to call GetToken on your own, caching of the token is something you must implement.

Ideally we would utilize the underlying MSAL library's cache. Unfortunately, currently it does not expose its cache directly. This may be something that becomes available in the future as a feature enhancement.

@jesperkristensen
Copy link

I have looked into using BearerTokenAuthenticationPolicy for caching TokenCredential for our internal service-to-service calls using HttpClient, but I gave up because BearerTokenAuthenticationPolicy is too coupled with a lot of HttpPipeline stuff, which seemed too complicated to use. So we are currently using TokenCredential without caching it for now.

@christothes christothes removed the needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team label May 3, 2021
@henriblMSFT
Copy link

We are in the same situation and have had to just copy the AccessTokenCache from the BearerTokenAuthenticationPolicy into our project. This is less then ideal because we would not benefit from any bug fixes or improvements from the original library.

If an ask needs to be made to the MSAL library so that we can use the cache with Azure.Identity I'm happy to create a request there but I personally feel like this feature should be part of the Azure.Identity.

If managed identities were never intended to be used for service to service authentication the guidance on managed identity should be updated to make this clear. I would be a big loss on ease of use of AAD auth for azure services though.

The Azure.Identity library also offers several additional benefits that MSAL doesn't provide by trying different types of authentication mechanism, this makes enabling debugging locally significantly easier then using the MSAL library where an engineer will not have access to the app credential.

@christothes
Copy link
Member

@henriblMSFT As I understand it, the request to expose the cache in MSAL has been made, but I don't think it would hurt to file an issue to indicate the customer need. If it were exposed, Azure.Identity would utilize that to manage cache automatically in more credentials.

@yufeih
Copy link

yufeih commented Jun 30, 2021

We are in the same situation here due to the push from ADAL to MSAL. We used to use AppAuthentication to access azure services that are not supported by azure SDK (SQL server and some of our own services we build using RBAC). AppAuthentication caches and refreshes the token internally for us but it is using ADAL.

To be compliant we want to move to DefaultAzureCredential but it lacks basic token cache and refresh. BearerTokenAuthenticationPolicy is not an option because it is coupled too much with Azure SDK's own HTTP pipeline and we just want a reliable way to retrieve the access token. Directly using MSAL losses the fallback chain. Today we have to build our own cache and copy it to multiple places, this is less than ideal.

Ideally Azure.Identity could reuse the cache from MSAL, but moving the caching feature already in Azure SDK from the BearerTokenAuthenticationPolicy layer down to DefaultAzureCredential layer might also be a viable option if that's simpler. We generally don't care about what is used internally behind DefaultAzureCredential as long as it implements proper token cache and fallback chain.

@christothes
Copy link
Member

@yufeih The cache implemented in BearerTokenAuthenticationPolicy is not ideal for use in a TokenCredential because it could be used across multiple service clients. MSAL's cache implements some fairly complex logic that we do not ever intend to duplicate in Azure.Identity.

@qetza
Copy link

qetza commented Jul 6, 2021

Hi @christothes,
So Azure.Identity will not provide a cache mechanism on top of TokenCredential and if we want to have token cached for mechanism which do not already have internal cache like MSAL we will need to implement it ourself?

@christothes
Copy link
Member

Hi @christothes,
So Azure.Identity will not provide a cache mechanism on top of TokenCredential and if we want to have token cached for mechanism which do not already have internal cache like MSAL we will need to implement it ourself?

If you are calling GetToken directly, that is correct for now.

@Meertman
Copy link

Meertman commented Sep 24, 2021

I have looked into using BearerTokenAuthenticationPolicy for caching TokenCredential for our internal service-to-service calls using HttpClient, but I gave up because BearerTokenAuthenticationPolicy is too coupled with a lot of HttpPipeline stuff, which seemed too complicated to use. So we are currently using TokenCredential without caching it for now.

I worked around this also by using the HttpPipelineBuilder as well, and got a working solution. However, it differs a lot from using the default approach which is using a HttpClient and/or HttpClientFactory for making HTTP requests that include the requested token.

An additional sidenote, the BearerTokenAuthenticationPolicy requires the usage of HTTPS. In our scenario, we use the library to retrieve access tokens from Azure Active Directory for a client application (an API) to authenticate to another one of our applications (another API). As both applications are hosted on pods in AKS in the same namespace, the communication between them runs over HTTP.

@christothes
Copy link
Member

closing this and tracking with #25361

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Azure.Identity Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. feature-request This issue requires a new behavior in the product in order be resolved.
Projects
None yet
Development

No branches or pull requests

8 participants