From cefa18a05688da46f7bd06f57781b281ec2d87c9 Mon Sep 17 00:00:00 2001 From: Luis Perez Morales <61613934+lperezmo@users.noreply.github.com> Date: Wed, 25 Mar 2026 15:25:59 -0700 Subject: [PATCH] Add upn fallback for single-tenant Microsoft/Azure AD authentication --- .../models/oauth2/microsoft_model.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/streamlit_authenticator/models/oauth2/microsoft_model.py b/streamlit_authenticator/models/oauth2/microsoft_model.py index e21569d9..1eafd506 100644 --- a/streamlit_authenticator/models/oauth2/microsoft_model.py +++ b/streamlit_authenticator/models/oauth2/microsoft_model.py @@ -141,15 +141,12 @@ def get_microsoft_user_info(self, auth_code: str) -> Dict[str, str]: st.rerun() token_json = self.decode_jwt(token_json['access_token']) keys = {'email', 'upn', 'family_name', 'given_name'} - return {key: token_json[key] for key in keys if key in token_json} - # user_info_url = 'https://graph.microsoft.com/v1.0/me' - # user_info_headers = { - # "Authorization": f"Bearer {token_json['access_token']}" - # } - # user_info_r = requests.get(user_info_url, headers=user_info_headers, timeout=10) - # if user_info_r.status_code != 200: - # raise LoginError('Failed to retrieve user information') - # return user_info_r.json() + user_info = {key: token_json[key] for key in keys if key in token_json} + # Single-tenant fix: Azure AD work/school tokens often omit 'email' + # but include 'upn' (User Principal Name) which serves the same purpose + if 'email' not in user_info and 'upn' in user_info: + user_info['email'] = user_info['upn'] + return user_info def guest_login(self) -> Union[str, Dict[str, str]]: """ Handles the login process and fetches user information or returns the authorization