...
Purpose: Proves user is authenticated and authorized for API calls Lifetime: 1 hour Contains:
- User ID
- User email
- Azure AD groups (for authorization)
- Expiration time
- Issuer (Microsoft Entra ID)
- Audience (ApiService)
Example (decoded):
{
"iss": "https://6073ce8b-73f3-4df4-9b80-5e40cdc6965f.ciamlogin.com/.../v2.0",
"aud": "api://4dad5d62-dc8c-4378-8bd0-ae736a4d73fe",
"sub": "abc123...",
"name": "John Doe",
"email": "john.doe@contractor.com",
"groups": ["ac6ec653-2ae3-457a-9302-d42429d83bee"],
"exp": 1733754123
}
...
Service: Components/Authentication/AuthenticationService/GraphUserService.cs Configuration: Program.cs:104-142 Usage: Admin pages, NavBar, Profile page
...
Security Mechanisms
PKCE (Proof Key for Code Exchange)
What: Random secret generated by MSAL.js before login Why: Prevents authorization code theft How: Code can only be exchanged by app that started the flow
Token Signature Validation
What: Cryptographic signature on every JWT token Why: Proves token issued by Microsoft, not forged How: ApiService downloads Microsoft's public keys, validates signature
Token Expiration
What: Every token has expiration timestamp Why: Limits damage if token stolen How: ApiService rejects expired tokens automatically
sessionStorage (Not localStorage)
What: Browser storage that clears when tab closes Why: Reduces risk if user leaves computer unlocked How: MSAL.js configured to use sessionStorage