MSAL, the Microsoft Authentication Library, helps developers implement authentication and authorization using Azure AD or Azure AD B2C. With a few lines of code, you can add the necessary functionality sign in users and secure resources. MSAL comes with a lot of built-in capabilities to help you do as little work as possible. MFA, Conditional Access and advanced features are available out of the box - no code needed. In many cases, token caching is also provided out of the box. For example, the default cache is in memory. This works great for most dev scenarios, like testing web apps and APIs.
However, there are certain scenarios that in-memory token caching doesn't work. Ideally, any workload deployed to production should have a persisted and scalable token cache.
In this blog post, we'll look at how to setup a file-based token cache for our Python-based daemon app. The reason why we need a token cache is because daemon apps are ephemeral. The app runs for a bit to execute a certain task and then terminates. The problem here is that without a token cache, every time we run the daemon, we have to authenticate and acquire a token from Azure AD - which is not efficient!
Let's build a cache.
Building the MSAL Python Cache
The good news is that we don't really have to do a lot of work for this. The MSAL team has already built an extension library for Python to provide the basic plumbing for our token cache.
In our existing Python app, we need to add the new library and implement a bit of code to set everything up.
Open the requirements.txt
, add the following and save the file:
msal-extensions>=0.3.0
We can now update our dependencies
pip install -r requirement.txt
Create a new file msalcache.py
and add the following code
import sys
import logging
from msal_extensions import *
def build_persistence(location, fallback_to_plaintext=False):
if sys.platform.startswith('win'):
return FilePersistenceWithDataProtection(location)
if sys.platform.startswith('darwin'):
return KeychainPersistence(location, "my_service_name", "my_account_name")
if sys.platform.startswith('linux'):
try:
return LibsecretPersistence(
location,
schema_name="my_schema_name",
attributes={"attr1": "hello", "attr2": "world"},
)
except:
if not fallback_to_plaintext:
raise
logging.exception("Encryption unavailable. Opting in to plain text.")
return FilePersistence(location)
That's it. We can now use this code to instantiate a cache and assign it to our MSAL Confidential Client.
Using the token cache with MSAL
Before instantiating our MSAL ConfidentialClient
we need to create a cache. Add the following code to console.py
(or your main code file)
persistence =msalcache.build_persistence("token_cache.bin")
print(f'The MSAL Cache supports encryption: {persistence.is_encrypted}')
cache = PersistedTokenCache(persistence)
Finally, we have to update our ConfidentialClient
client to use the cache. Update the code as per below:
app = msal.ConfidentialClientApplication(
client_id=config["client_id"],
client_credential=aad_client_secret.value,
authority=config["authority"],
token_cache=cache
)
That's it!
Running the code from now on will make use of the cache and the call the acquire_token_silent()
will yield an access token after the first time we run our daemon :)
You can get the source code for this project from our GitHub repo
If you want to learn more about the MSAL for Python library, you can read the docs here
Top comments (0)