Implemented complete Microsoft Authentication Library (MSAL) / Azure AD Single Sign-On (SSO) system following Ferrero app pattern. KEY FEATURE: Toggle authentication on/off via environment variable - SSO_ENABLED=false → Mock user, no login required (local dev) - SSO_ENABLED=true → Full Azure AD authentication (production) NEW FILES: - composer.json - Firebase JWT dependency - .env.example - Environment variable template - env_loader.php - Parse .env file - JWTValidator.php - Validate JWT tokens from Azure AD - AuthMiddleware.php - Core auth orchestrator with login UI - auth.php - Authentication API (login/logout/status) - auth-test.php - Debug authentication status - AUTH_README.md - Complete setup documentation UPDATED FILES: - config.php - Load env vars, add SSO constants - index.php - Require auth, add logout button, MSAL script - api.php - Add authentication check - enhance_prompt.php - Add authentication check - .gitignore - Exclude .env and vendor/ AUTHENTICATION FLOW: 1. User visits app → Auth check 2. If SSO disabled → Mock "Local Developer" user 3. If SSO enabled → Validate JWT from cookie 4. If no token → Show MSAL login page 5. User signs in → Token validated → Cookie set → App loads SECURITY FEATURES: ✅ httpOnly cookies (XSS prevention) ✅ SameSite=Lax (CSRF prevention) ✅ JWT signature validation ✅ Claims validation (exp, nbf, aud, iss) ✅ JWKS from Azure AD ✅ 24-hour token expiration ✅ Secure flag for HTTPS DEPENDENCIES INSTALLED: - firebase/php-jwt v6.11.1 TESTING: - Local: SSO disabled by default in .env - Server: Set SSO_ENABLED=true with Azure AD credentials - Cannot test MSAL locally (redirect URI bound to server) DEPLOYMENT: 1. Install composer dependencies 2. Configure .env with Azure AD credentials 3. Set SSO_ENABLED=true when ready 4. Visit auth-test.php to verify setup 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
8 KiB
MSAL Authentication Setup Guide
Overview
Nano Banana Pro now includes Microsoft Authentication Library (MSAL) / Azure AD Single Sign-On (SSO) authentication. The authentication can be toggled on/off via environment variable for seamless testing and deployment.
Quick Start
Local Development (No Authentication)
# 1. Ensure .env file exists with:
SSO_ENABLED=false
# 2. Run the app normally in MAMP
# All users get mock "Local Developer" credentials
# No login required
Production (with SSO)
# 1. Update .env file:
SSO_ENABLED=true
SSO_TENANT_ID=your-azure-tenant-id
SSO_CLIENT_ID=your-azure-application-id
# 2. Deploy to server
# 3. Users must login with Microsoft account
Installation Steps
1. Install Dependencies
cd /Users/daveporter/Desktop/CODING-2024/NANO-RESEARCH
composer install
This installs the Firebase JWT library required for token validation.
2. Configure Environment
# Copy example file
cp .env.example .env
# Edit .env and set:
SSO_ENABLED=false # Start with authentication disabled
3. Azure AD Setup (When Enabling SSO)
Create Azure AD App Registration:
- Go to Azure Portal
- Navigate to: Azure Active Directory → App registrations → New registration
- Set name: "Nano Banana Pro"
- Set redirect URI:
https://your-server-url.com/path/to/app/index.php - Click Register
Get Credentials:
- Copy Application (client) ID → This is your
SSO_CLIENT_ID - Copy Directory (tenant) ID → This is your
SSO_TENANT_ID - Go to Authentication → Enable ID tokens checkbox
- Go to API permissions → Add:
openid,profile,email
Update .env:
SSO_ENABLED=true
SSO_TENANT_ID=e519c2e6-bc6d-4fdf-8d9c-923c2f002385
SSO_CLIENT_ID=9079054c-9620-4757-a256-23413042f1ef
File Structure
New Files Created:
/NANO-RESEARCH/
├── composer.json # PHP dependencies (Firebase JWT)
├── .env # Environment config (gitignored)
├── .env.example # Template for environment variables
├── env_loader.php # Loads .env file
├── JWTValidator.php # JWT token validation logic
├── AuthMiddleware.php # Auth orchestrator + login UI
├── auth.php # Auth API endpoint
├── auth-test.php # Debugging page
├── AUTH_README.md # This file
└── vendor/ # Composer dependencies (gitignored)
Modified Files:
config.php # Added SSO constants
index.php # Added auth check, logout button
api.php # Added auth check
enhance_prompt.php # Added auth check
.gitignore # Added .env and vendor/
How It Works
When SSO_ENABLED=false (Testing Mode)
- User visits app
- AuthMiddleware returns mock "Local Developer" user
- No login page shown
- All features work normally
- Perfect for local testing
When SSO_ENABLED=true (Production Mode)
- User visits app
- AuthMiddleware checks for
auth_tokencookie - If no token → Show MSAL login page
- User clicks "Sign In with Microsoft"
- MSAL popup opens for Azure AD login
- User authenticates
- Token sent to
auth.phpfor validation - JWT validated against Azure AD public keys
- Token stored in httpOnly cookie (24 hours)
- User redirected to app
- Logout button visible in header
Testing
Test Authentication Status
Visit: http://your-server/auth-test.php
Shows:
- SSO configuration (enabled/disabled)
- Tenant ID and Client ID
- Current authentication status
- User information
- Cookie presence
Test Locally (SSO Disabled)
# 1. Set SSO_ENABLED=false in .env
# 2. Open app in MAMP
# 3. Should see "Welcome, Local Developer" (if SSO was previously enabled)
# 4. App functions normally
# 5. No login/logout buttons
Test on Server (SSO Enabled)
# NOTE: Cannot test locally - Azure AD requires exact redirect URI match
# 1. Deploy to production server
# 2. Set SSO_ENABLED=true in .env on server
# 3. Add Azure AD credentials to .env
# 4. Visit app URL
# 5. Should see login page
# 6. Click "Sign In with Microsoft"
# 7. Complete Microsoft login
# 8. Should redirect to app
# 9. Should see "Welcome, [Your Name]" and logout button
Security Features
✅ httpOnly Cookies - Prevents XSS attacks (JavaScript can't access token)
✅ SameSite=Lax - Prevents CSRF attacks
✅ Secure Flag - Cookie only sent over HTTPS in production
✅ JWT Validation - Cryptographic verification of tokens
✅ Expiration Check - Validates exp claim
✅ Not-Before Check - Validates nbf claim
✅ Audience Validation - Ensures token is for our app
✅ Issuer Validation - Ensures token from Azure AD
✅ JWKS Verification - Uses Azure AD public keys
✅ 24-Hour Expiration - Tokens expire after 1 day
Troubleshooting
Login Page Shows But Can't Login
- Check Azure AD app registration has correct redirect URI
- Ensure
SSO_TENANT_IDandSSO_CLIENT_IDare correct - Check browser console for MSAL errors
- Visit
auth-test.phpto verify configuration
"Authentication Required" Error
- Check
auth_tokencookie exists (browser dev tools) - Token may have expired (24-hour limit)
- Try logging out and back in
- Check
auth-test.phpfor token status
SSO Not Disabling
- Verify
.envhasSSO_ENABLED=false(not "false" in quotes) - Clear browser cookies
- Restart PHP server/MAMP
- Check
auth-test.phpshows "SSO Enabled: NO"
Token Validation Failing
- Check server can reach Azure AD endpoints
- Verify tenant ID and client ID match Azure AD
- Check token hasn't expired
- Review
error_logfor JWT validation details
API Endpoints
Login
POST /auth.php
Content-Type: application/json
{
"action": "login",
"idToken": "eyJ0eXAiOiJKV1QiLCJhbGci...",
"accessToken": "eyJ0eXAiOiJKV1QiLCJhbGci..."
}
Logout
POST /auth.php
Content-Type: application/json
{
"action": "logout"
}
Status Check
POST /auth.php
Content-Type: application/json
{
"action": "status"
}
Maintenance
Rotating Credentials
- Update Azure AD app registration
- Update
.envwith new credentials - No code changes needed
- Existing sessions remain valid until cookie expires
Disabling SSO Temporarily
# In .env:
SSO_ENABLED=false
# Immediately disables SSO for all users
# No restart needed
# Users get mock "Local Developer" access
Monitoring
- Check
error_logfor authentication failures - Monitor Azure AD sign-in logs
- Track failed login attempts
- Review token validation errors
Production Checklist
Before enabling SSO in production:
- Composer dependencies installed (
vendor/directory exists) .envfile configured with Azure AD credentials- Azure AD app registration created
- Redirect URI matches production URL exactly
- ID tokens enabled in Azure AD app
- API permissions added (
openid,profile,email) - HTTPS enabled on production server
auth-test.phpshows correct configuration- Test login/logout flow works
- Error logging enabled
Support
For issues with:
- MSAL errors: Check MSAL.js documentation
- Azure AD setup: Check Azure AD app registration guide
- JWT validation: Check Firebase JWT library logs in
error_log - Configuration: Run
auth-test.phpto see current setup
Important Notes
- Cannot test MSAL locally - Azure AD requires exact URL match
- Testing happens on server after deployment
- SSO toggle allows testing without auth before enabling
- httpOnly cookies mean token not accessible via JavaScript
- 24-hour token expiration - users must re-login daily
- Mock user (
dev@localhost) used when SSO disabled