AzureAD / microsoft-authentication-library-for-python

Microsoft Authentication Library (MSAL) for Python makes it easy to authenticate to Microsoft Entra ID. General docs are available here https://learn.microsoft.com/entra/msal/python/ Stable APIs are documented here https://msal-python.readthedocs.io. Questions can be asked on www.stackoverflow.com with tag "msal" + "python".
https://stackoverflow.com/questions/tagged/azure-ad-msal+python
Other
756 stars 191 forks source link

[Feature Request] Improve default token caching #602

Closed bgavrilMS closed 8 months ago

bgavrilMS commented 9 months ago

As a repair item from incidents where client_credentils apps were not using cached tokens:

rayluo commented 9 months ago

Produce an indication that the token comes from the cache (e.g. boolean AuthenticationResult.IsFromCache or AuthenticationResult.TokenSource - IdP, TokenCache, Broker)

While it is easy to add this indication into our public API, how do we envision app developers to utilize it programmatically? It is not actionable to them to do "if TokenSource != TokenCache then DoSomething()", because cache miss is a fairly common event, especially in CAE.

Perhaps what we really want is to guide app developer to persist and reuse token cache. A better indicator can therefore be "is the current token cache completely empty (note that expired tokens still count as non-empty cache)". If the cache is empty, then it is likely the calling app did not persist the cache correctly, which warrants MSAL to emit a warning log and/or send telemetry. No public API change is required for this proposal.

Allow apps to do static caching (i.e. shared per process), e.g. cca.WithCacheOptions(SharedCache)

MSAL Python's cache parameter always allow flexible caching. For example:

import msal

global_cache = msal.TokenCache()  # Now this becomes a static cache

# For whatever reason, multiple CCA will be created, but they can all share the same token cache
for i in range(10):
    cca = msal.ConfidentialClientApplication(
        "my_client_id",
        client_credential=...,
        ...,
        cache=global_cache)
    token = cca.acquire_token_for_client(["scope"])

Update client_creds samples to showcase the 2 new APIs.

Looks like no new API is necessary. But we can and shall add a new sample to demonstrate the shared token cache pattern, which can be useful in the "pre-calculated client assertion" scenario.

We can discuss (online or offline) on those proposals above, or I can proceed to draft some PRs to further demonstrate those proposals. Let me know.

bgavrilMS commented 9 months ago

On the topic of TokenSource

We exposed this in .NET and JS and app developers are encouraged to monitor TokenSource in their apps. It is not intended to be used to take action based on it. Have a look here at other "metrics" MSAL .NET exposes to app developers: https://learn.microsoft.com/en-us/entra/msal/dotnet/advanced/high-availability#add-monitoring-around-msal-operations

On top of this, it makes it easier to for the MSAL team (us) to write tests.

On the topic of the static cache

Your proposal looks good to me, please update the client_credentials sample to use this.

Aside: what do your web app / web api samples do? Cache at the session level?

rayluo commented 9 months ago

A FYI on the static cache topic. Many of the existing samples already mentioned that cache parameter, with link to document. Now that we are going to change this samples anyway, I plan to actually demonstrate the "persist token cache on disk and reload it in next run" pattern. I'll send out a PR for you to review. @bgavrilMS

bgavrilMS commented 9 months ago

Agree on persisting the cache to disk for public client samples.

But confidential clients don't really make that much use of I/O. Besides, in some Azure environments you don't even have access to the disk.