Reuse Azure AD login refresh/access token

If you’re creating a debugging post, please include the following info:

  1. Are you running your app locally or is it deployed? deployed

  2. If your app is deployed:
    a. Is it deployed on Community Cloud or another hosting platform? AWS EC2
    b. Share the link to the public deployed app.

  3. Share the link to your app’s public GitHub repository (including a requirements file).

  4. Share the full text of the error message (not a screenshot).
    i have integrated with my company SSO using msal package. it is getting successfully logged in. but when i refresh the page it ask me to sign in again. im not able to reuse the token.

  5. Share the Streamlit and Python versions.
    Streamlit, version 1.39.0
    Python 3.9.16

import streamlit as st
import msal
import requests
import os

# Replace with your own values
CLIENT_ID = '****'
CLIENT_SECRET = '****'
TENANT_ID = '****'

AUTHORITY = f'https://login.microsoftonline.com/{TENANT_ID}'
SCOPE = ["User.ReadBasic.All"]
REDIRECT_URI = '****'

# Define the path for the token cache file
CACHE_FILE = 'token_cache.bin'

# Function to load the token cache from a file
def load_token_cache():
    if os.path.exists(CACHE_FILE):
        with open(CACHE_FILE, 'rb') as f:
            cache = msal.SerializableTokenCache()
            cache.deserialize(f.read().decode('utf-8'))
            return cache
    return msal.SerializableTokenCache()

# Function to save the token cache to a file
def save_token_cache(cache):
    with open(CACHE_FILE, 'wb') as f:
        f.write(cache.serialize().encode('utf-8'))

# Load the token cache
token_cache = load_token_cache()

# Create the MSAL application with the loaded token cache
app = msal.ConfidentialClientApplication(CLIENT_ID, authority=AUTHORITY, client_credential=CLIENT_SECRET, token_cache=token_cache)

def get_auth_url():
    auth_url = app.get_authorization_request_url(SCOPE, redirect_uri=REDIRECT_URI)
    return auth_url

def get_token_from_code(auth_code):
    result = app.acquire_token_by_authorization_code(auth_code, scopes=SCOPE, redirect_uri=REDIRECT_URI)
    st.write(result)
    return result['access_token']

def get_user_info(access_token):
    headers = {'Authorization': f'Bearer {access_token}'}
    response = requests.get('https://graph.microsoft.com/v1.0/me', headers=headers)
    return response.json()

def handle_redirect():
    query_params = st.experimental_get_query_params()
    if 'code' in query_params:
        code = query_params['code'][0]
        access_token = get_token_from_code(code)
        st.session_state['access_token'] = access_token
        st.session_state['is_authenticated'] = True
        st.experimental_set_query_params()  # Clear the query params to prevent re-triggering the auth flow
        save_token_cache(token_cache)

def setup_page(page_title):
    st.set_page_config(page_title=page_title, page_icon="👋")

    if 'access_token' not in st.session_state:
        handle_redirect()

    access_token = st.session_state.get('access_token')
    is_authenticated = st.session_state.get('is_authenticated', False)

    if not access_token and token_cache.has_state_changed:
        accounts = app.get_accounts()
        if accounts:
            result = app.acquire_token_silent(SCOPE, account=accounts[0])
            if 'access_token' in result:
                access_token = result['access_token']
                st.session_state['access_token'] = access_token
                st.session_state['is_authenticated'] = True

    if access_token and is_authenticated:
        user_info = get_user_info(access_token)
        st.session_state['user_info'] = user_info
        return True
    else:
        st.write("Please sign-in to use this app.")
        auth_url = get_auth_url()
        st.markdown(f"<a href='{auth_url}' target='_self'>Sign In</a>", unsafe_allow_html=True)
        st.stop()

setup_page("Home")
st.write("Welcome to the Azure AI Demo Platform!")

if 'user_info' in st.session_state:
    st.write("User info:", st.session_state['user_info'])

any help here on this

If you reload the page (or open it in another tab, or lose connectivity for too long), Streamlit will create a new session. That means that "user_info" and "access_token" won’t be in Session State any more.

So that means app.acquire_token_by_authorization_code needs to be able to blindly pick up on an existing token. I’m not deeply familiar with the library, so I’m not sure how that call works exactly…