Not sure What else is missing or needs to be done! Any Help would be appreciated
Error:
AADSTS500133: Assertion is not within its valid time range. Ensure that the access token is not expired before using it for user assertion, or request a new token.
I have two Apps registered for my Azure WebApp that call Foundry agents using Python SDK and Streamlit UI which in turn connects to Fabric Data Agent. Had to go via this OBO route due to the following reason: https://community.fabric.microsoft.com/t5/Fabric-platform/Fabric-Data-Agent-inaccessible-from-Azure-WebApp-using-Foundry/m-p/4915477#M24463
The App Service WebApp has the Auth App added as Identity provider with all the following properties enabled:
App Service authentication --> Enabled
Restrict access --> Require authentication
Unauthenticated requests --> Return HTTP 302 Found (Redirect to identity provider)
Redirect to --> Microsoft
Token store --> Enabled
Registered Apps:
Auth App registration for Authentication code (for use by either MSAL or Easy Auth (Settings > Authentication > Add identity provider in the Web App resource)
The Auth App has Redirect URI configured in the following format: https://
.azurewebsites.net/.auth/login/aad/callback and it also has both Access tokens and ID tokens enabled in SPA Settings The Auth App also has APP ID Uri configured in the Expose API section, has a scope created and also has a Client application authorized for the SDK App
SDK App registration for the application (for use by body of code that is using the Azure SDK for Python). This is a SEPARATE app registration from the one used for authentication.
Auth App permissions: (All the permissions have been granted Admin Consent from portal as well as using the Consent URL in browser)
1. SDK App--> user_impersonation (delegated)
2. Microsoft Graph --> profile / Presence.Read.All / User.Read.All / User.ReadBasic.All (delegated)
SDK App permissions: All the permissions have been granted Admin Consent from portal as well as using the Consent URL in browser)
1. Azure Service Management--> user_impersonation (delegated)
2. Microsoft Graph --> Presence.Read.All / User.Read.All / User.ReadBasic.All
3. Power Bi Service --> DataAgent.ReadWrite.All / Tenant.ReadWrite.All (Both Delegated and Application)
When I tried debugging my code, I could see the following: Token Type (typ): JWT Algorithm (alg): RS256 Audience (aud): api://
My OBO Code:
def get_user_access_token():
"""
Retrieve user access token from Easy Auth headers.
This token is issued for the AUTH app registration.
"""
# Check session cache first
if "user_access_token" in st.session_state:
return st.session_state.user_access_token
try:
# Get headers from Streamlit context
headers = st.context.headers
# Easy Auth exposes the token in this header
access_token = headers.get("X-Ms-Token-Aad-Access-Token")
if not access_token:
# Try alternative header names
access_token = (
headers.get("x-ms-token-aad-access-token") or
headers.get("HTTP_X_MS_TOKEN_AAD_ACCESS_TOKEN")
)
if access_token:
print("✓ Access token retrieved from Easy Auth headers")
# Decode and print token info for debugging
import base64
import json
try:
parts = access_token.split('.')
if len(parts) == 3:
payload = parts[1]
payload += '=' * (4 - len(payload) % 4)
decoded = base64.urlsafe_b64decode(payload)
claims = json.loads(decoded)
print(f"DEBUG: Token audience: {claims.get('aud', 'unknown')}")
print(f"DEBUG: Token app ID: {claims.get('appid', 'unknown')}")
print(f"DEBUG: Token scopes: {claims.get('scp', 'unknown')}")
except Exception as e:
print(f"DEBUG: Could not decode token: {e}")
st.session_state.user_access_token = access_token
return access_token
else:
print("DEBUG: Available headers:")
for key, value in headers.items():
display_value = value[:40] + "..." if len(value) > 40 else value
print(f" {key}: {display_value}")
raise Exception("X-Ms-Token-Aad-Access-Token header not found")
except AttributeError:
raise Exception(
"Could not access st.context.headers. "
"Ensure you're using Streamlit version that supports st.context"
)
except Exception as e:
raise Exception(f"Error retrieving access token: {str(e)}")
def get_obo_credential():
"""
Create On-Behalf-Of credential using the SDK app registration.
This exchanges the user's token (for AUTH app) to a token for SDK app.
"""
user_assertion = get_user_access_token()
if not user_assertion:
raise Exception("User assertion token not found")
# Create OBO credential with SDK app registration details
return OnBehalfOfCredential(
tenant_id=SDK_APP_TENANT_ID,
client_id=SDK_APP_CLIENT_ID,
client_secret=SDK_APP_CLIENT_SECRET,
user_assertion=user_assertion,
)
def get_cached_obo_credential():
"""
Cache the OBO credential in session state to avoid recreating it.
"""
if "obo_cred" not in st.session_state:
try:
st.session_state.obo_cred = get_obo_credential()
print("✓ OBO credential created successfully")
except Exception as e:
print(f"❌ Failed to create OBO credential: {e}")
raise
return st.session_state.obo_cred
Referred the following: Attempting to use the Azure Web App 'Identity provider' feature with a web app that uses the Python Azure SDK (azure.identity)