diff --git a/backend/app/services/auth_service.py b/backend/app/services/auth_service.py index 5cc6cb2..8745c6f 100755 --- a/backend/app/services/auth_service.py +++ b/backend/app/services/auth_service.py @@ -82,6 +82,15 @@ async def verify_access_token(token: str) -> Optional[dict]: alg = unverified_header.get("alg") logger.info(f"[MSAL Backend] Token header - kid: {kid}, alg: {alg}") + # Log unverified claims to see what we're receiving + try: + unverified_claims = jwt.get_unverified_claims(token) + logger.info(f"[MSAL Backend] Token aud (unverified): {unverified_claims.get('aud')}") + logger.info(f"[MSAL Backend] Token iss (unverified): {unverified_claims.get('iss')}") + logger.info(f"[MSAL Backend] Token azp (unverified): {unverified_claims.get('azp')}") + except Exception as e: + logger.warning(f"[MSAL Backend] Could not decode unverified claims: {e}") + if not kid: logger.warning("[MSAL Backend] No key ID in token header") return None diff --git a/frontend/services/authConfig.ts b/frontend/services/authConfig.ts index 9dd1ebc..41e11e6 100755 --- a/frontend/services/authConfig.ts +++ b/frontend/services/authConfig.ts @@ -4,10 +4,13 @@ */ import { Configuration, LogLevel, PopupRequest } from '@azure/msal-browser'; +// Client ID used for both MSAL config and API token requests +const CLIENT_ID = import.meta.env.VITE_AZURE_CLIENT_ID || ''; + // MSAL configuration - uses PKCE by default for SPAs export const msalConfig: Configuration = { auth: { - clientId: import.meta.env.VITE_AZURE_CLIENT_ID || '', + clientId: CLIENT_ID, authority: `https://login.microsoftonline.com/${import.meta.env.VITE_AZURE_TENANT_ID || 'common'}`, redirectUri: import.meta.env.VITE_AZURE_REDIRECT_URI || window.location.origin, postLogoutRedirectUri: window.location.origin, @@ -41,13 +44,13 @@ export const msalConfig: Configuration = { }, }; -// Scopes for the access token -// Using basic OpenID scopes for authentication +// Scopes for initial login (ID token) export const loginRequest: PopupRequest = { scopes: ['openid', 'profile', 'email'], }; -// Scopes for API calls (same as login for this app) +// Scopes for API calls - request token for OUR app, not Graph +// Using the client ID as scope requests an access token for this app export const apiTokenRequest = { - scopes: ['openid', 'profile', 'email'], + scopes: [`${CLIENT_ID}/.default`], };