Step-by-Step Process & Entities
1. Developer/Tester (Browser)
- Person accessing Swagger UI for API testing
- Can be a developer, QA tester, or technical user
- Uses their Microsoft credentials to authenticate with Swagger
2. Swagger UI (Interactive API Documentation)
- Web-based API documentation and testing interface
- Built into both ApiService and IntegrationServiceAPI
- Location:
/swaggerendpoint (e.g.,http://localhost:7532/swagger) - Allows developers to test API endpoints interactively
- Uses Scalar UI for enhanced API documentation
3. Microsoft Entra ID (Azure AD Tenant)
- Microsoft's cloud identity service
- Stores developer credentials and profiles
- Tenant ID:
6073ce8b-73f3-4df4-9b80-5e40cdc6965f - Issues JWT tokens after successful authentication
- Hosted by Microsoft (external service)
4. Swagger Client Application
- Azure AD app registration specifically for Swagger UI
- Client ID:
84c38b43-12e4-4c26-8292-8910d79aa532 - Type: Single Page Application (SPA) with PKCE enabled
- Registered in the same Azure AD tenant
5. ApiService (Backend REST API)
- Core backend API
- Location:
Source/EGU.PartnerPortal.ApiService - Swagger URL:
http://localhost:7532/swagger(local) - Client ID:
4dad5d62-dc8c-4378-8bd0-ae736a4d73fe - Scope:
api://4dad5d62-dc8c-4378-8bd0-ae736a4d73fe/access_as_user
6. IntegrationServiceAPI (Integration REST API)
- External system integration API
- Location:
Source/EGU.PartnerPortal.IntegrationServiceAPI - Swagger URL:
http://localhost:7098/swagger(local) - Client ID:
bd5100ee-af63-4880-8c60-47d4207d60c1 - Scope:
api://bd5100ee-af63-4880-8c60-47d4207d60c1/access_as_user
High-Level Authorization Flows
Flow 1: Developer Opens Swagger & Authenticates (Steps 1-6)
┌─────────────────────────────────────────────────────────────────┐
│ SWAGGER AUTHENTICATION FLOW (Steps 1-6) │
└─────────────────────────────────────────────────────────────────┘
┌──────────────┐
│ Developer │
│ Browser │
└──────┬───────┘
│
│ Step 1: Navigate to Swagger UI
│ (http://localhost:7532/swagger)
▼
┌──────────────────────┐
│ Swagger UI Page │
│ (Unauthenticated) │
└──────┬───────────────┘
│
│ Step 2: Click "Authorize" button
│ Select oauth2 security scheme
▼
┌──────────────────────────────┐
│ Swagger Authorization Modal │
│ Shows required scopes │
└──────┬───────────────────────┘
│
│ Step 3: Click "Authorize"
│ → Redirect to Microsoft login
▼
┌──────────────────────────────┐
│ Microsoft Entra ID │
│ Login Page │
└──────┬───────────────────────┘
│
│ Step 4: User enters
│ email + password + MFA
▼
┌──────────────────────────────┐
│ Microsoft Entra ID │
│ Validates Credentials │
└──────┬───────────────────────┘
│
│ ✅ Valid credentials
│
│ Step 5: Returns
│ authorization code
▼
┌──────────────────────┐
│ Swagger UI │
│ (PKCE exchange) │
└──────┬───────────────┘
│
│ Step 6: Exchange code
│ for access token
▼
┌──────────────────────────────┐
│ Microsoft Entra ID │
│ Token Endpoint │
└──────┬───────────────────────┘
│
│ Returns access token (1h)
▼
┌────────────────────────────────┐
│ ✅ SWAGGER AUTHORIZED │
│ Can test API endpoints │
└────────────────────────────────┘
Flow 2: Testing API Endpoint with Token (Steps 7-8)
┌─────────────────────────────────────────────────────────────────┐ │ API TEST & VALIDATION FLOW (Steps 7-8) │ └─────────────────────────────────────────────────────────────────┘ ┌────────────────────────────────┐ │ Developer clicks "Try it out"│ │ on an API endpoint │ └────────────┬───────────────────┘ │ │ Step 7: Swagger adds token to request ▼ ┌──────────────────────────────────┐ │ HTTP Request │ │ GET /api/v1/WorkOrder/Overview │ │ Authorization: Bearer eyJ... │ └──────┬───────────────────────────┘ │ │ Step 8: Request received ▼ ┌──────────────────────────────────────┐ │ ApiService/IntegrationServiceAPI │ │ JWT Authentication Middleware │ └──────┬───────────────────────────────┘ │ │ Token Validation: │ ✓ Issuer (Azure AD tenant) │ ✓ Audience (this API) │ ✓ Signature (Azure AD keys) │ ✓ Expiration (not expired) │ ├─── ✅ Valid ────┐ ❌ Invalid ───┐ │ │ │ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Controller │ │ 200 OK │ │ 401/403 │ │ Executes │ │ Returns │ │ Unauthorized│ │ Endpoint │ │ Data │ │ Forbidden │ └──────────────┘ └──────────────┘ └──────────────┘
Step-by-Step Authorization Process
Step 1: Developer Opens Swagger UI
What happens:
- Developer navigates to Swagger UI endpoint
- ApiService:
http://localhost:7532/swagger(local dev) - IntegrationServiceAPI:
http://localhost:7098/swagger(local dev)
- ApiService:
- Swagger UI loads, showing all available API endpoints
- All endpoints show a lock icon 🔒 indicating authorization required
Who's involved:
- Developer (Browser)
- Swagger UI
What you see:
- List of all API endpoints organized by controller
- Open lock icons (grayed out) indicating authentication required
- "Authorize" button in the top-right corner
Result:
- Swagger UI is loaded but cannot test endpoints yet
- Need to authenticate first
Step 2: Click "Authorize" Button
What happens:
- Developer clicks the "Authorize" button (or clicks a lock icon)
- Modal dialog appears showing available security schemes
- Shows OAuth2 (Authorization Code with PKCE) security scheme
- Displays the required scope for the API
Who's involved:
- Developer
- Swagger UI
Authorization modal shows:
For ApiService:
oauth2 (OAuth2, authorizationCode with PKCE)
Scopes:
api://4dad5d62-dc8c-4378-8bd0-ae736a4d73fe/access_as_user - Access API as user
For IntegrationServiceAPI:
oauth2 (OAuth2, authorizationCode with PKCE)
Scopes:
api://bd5100ee-af63-4880-8c60-47d4207d60c1/access_as_user - Access Integration API as user
Result:
- Developer sees what permissions will be requested
- Ready to start OAuth2 flow
Step 3: Initiate OAuth2 Flow
What happens:
- Developer clicks "Authorize" in the modal
- Swagger UI starts the OAuth2 Authorization Code flow
- Browser redirects to Microsoft Entra ID login page
- Security code (PKCE) generated automatically
Who's involved:
- Swagger UI
- Microsoft Entra ID
What's sent to Microsoft:
- Swagger client ID
- Which API scope is needed
- Security challenge code (PKCE)
- Where to redirect back after login
Result:
- Browser redirected to Microsoft login page
Step 4: Developer Enters Credentials
What happens:
- Developer sees Microsoft login page
- Enters email (e.g.,
developer@example.com) - Enters password
- Completes MFA challenge (required)
- (First time only) Consents to app permissions
Who's involved:
- Developer
- Microsoft Entra ID
What Microsoft validates:
- User credentials are correct
- User has access to the tenant
- User consents to requested scope
Result:
- Microsoft Entra ID validates credentials
- If valid → Proceed to Step 5
- If invalid → Show error, retry
Step 5: Authorization Code Returned
What happens:
- Microsoft Entra ID generates a one-time authorization code
- Redirects browser back to Swagger's callback page
- Code is valid for 10 minutes
Who's involved:
- Microsoft Entra ID
- Swagger UI
Result:
- Swagger UI receives authorization code
- Ready to exchange code for access token
Step 6: Exchange Code for Access Token
What happens:
- Swagger UI automatically exchanges authorization code for access token
- Sends code + PKCE verifier to Microsoft token endpoint
- Microsoft validates code and PKCE verifier
- Returns access token
Who's involved:
- Swagger UI
- Microsoft Entra ID
What's in the access token:
- Who issued it (Microsoft Entra ID)
- Who it's for (ApiService or IntegrationServiceAPI)
- Developer's identity (name and email)
- What permissions are granted
- When it expires (1 hour)
Result:
- Swagger UI now has access token (valid for 1 hour)
- Authorization modal closes
- Lock icons change to closed locks (black) indicating authorized
- Developer can now test endpoints
Step 7: Testing an API Endpoint
What happens (every time developer tests an endpoint):
- Developer selects an endpoint (e.g.,
GET /api/v1/WorkOrder/Overview) - Clicks "Try it out"
- Fills in any required parameters
- Clicks "Execute"
- Swagger UI automatically adds the access token to the request
- Request sent to the API
Who's involved:
- Developer
- Swagger UI
- ApiService or IntegrationServiceAPI
Result:
- API receives authenticated request with token
- Token proves developer's identity and permissions
Step 8: API Validates Token
What happens (on ApiService/IntegrationServiceAPI):
- API receives request with token
- Authentication middleware examines the token
- Checks who issued the token (Azure AD)
- Validates token is authentic:
- Signature is valid (proves token came from Azure AD)
- Issuer matches (correct Azure AD tenant)
- Audience matches (token is for this specific API)
- Not expired (within 1-hour lifetime)
- If all checks pass → Request continues to controller
- If any check fails → Return 401 Unauthorized
Who's involved:
- ApiService or IntegrationServiceAPI
- JWT Authentication Middleware
- Microsoft Entra ID (public keys used for validation)
What's validated:
- Token signature: Proves it's authentic and not forged
- Issuer: Confirms it came from Azure AD
- Audience: Ensures it's for the correct API
- Expiration: Checks it hasn't expired
Result:
- ✅ Valid token → Controller executes, returns response (200 OK)
- ❌ Invalid token → Authentication fails, returns 401 Unauthorized
- Swagger UI displays the response
Environment-Based Access Control
Swagger UI access varies by environment for security:
Development Environment (Local)
- Access: Fully open - anyone on localhost can use Swagger
- URL:
http://localhost:7532/swaggerorhttp://localhost:7098/swagger
Testing/Staging/UAT Environments
- Access: IP whitelist required - only approved IP addresses can access
- Restriction: Returns 403 Forbidden if IP not on whitelist
- 📄 See: Swagger IP Whitelisting Documentation
Production Environment
- Access: Completely disabled for security
- Result: Swagger endpoints return 404 Not Found
Token Details
Access Token (JWT)
Purpose: Proves developer is authenticated and authorized to call API endpoints
Lifetime: 1 hour
What's in the token:
- Audience: Which API this token is for (ApiService or IntegrationServiceAPI)
- Issuer: Microsoft Entra ID (proves it came from Azure AD)
- Expiration: When the token expires
- User identity: Developer's name and email
- Permissions: What the developer can access (scope)
- Signature: Cryptographic proof the token is authentic
When token expires:
- After 1 hour, developer must click "Authorize" again
- No automatic refresh (unlike the Web app)
- Lock icons change back to open (grayed out)
Security Mechanisms
PKCE (Proof Key for Code Exchange)
What it does: Protects the authorization code during the OAuth2 flow Why it matters: Prevents attackers from stealing and using authorization codes How it works: Swagger UI automatically generates a secret code that only it knows, making stolen authorization codes useless
Token Signature Validation
What it does: Verifies each token was actually issued by Microsoft Why it matters: Prevents forged or tampered tokens How it works: Azure AD signs tokens with a private key, and the API verifies the signature using Azure AD's public key
Token Expiration
What it does: Tokens automatically expire after 1 hour Why it matters: Limits damage if a token is stolen What happens: Developer must re-authorize in Swagger to get a new token
Audience Validation
What it does: Ensures tokens are used for the intended API only Why it matters: Prevents using an ApiService token for IntegrationServiceAPI (and vice versa) How it works: Each API only accepts tokens specifically issued for it
Issuer Validation
What it does: Verifies tokens come from the correct Azure AD tenant Why it matters: Prevents tokens from other organizations' Azure AD How it works: API only accepts tokens from the configured tenant ID
Quick Reference
ApiService
| Property | Value |
|---|---|
| Swagger URL (Local) | http://localhost:7532/swagger |
| API Client ID | 4dad5d62-dc8c-4378-8bd0-ae736a4d73fe |
| Swagger Client ID | 84c38b43-12e4-4c26-8292-8910d79aa532 |
IntegrationServiceAPI
| Property | Value |
|---|---|
| Swagger URL (Local) | http://localhost:7098/swagger |
| API Client ID | bd5100ee-af63-4880-8c60-47d4207d60c1 |
| Swagger Client ID | 84c38b43-12e4-4c26-8292-8910d79aa532 |
Common Values
| Property | Value |
|---|---|
| Tenant ID | 6073ce8b-73f3-4df4-9b80-5e40cdc6965f |
| Token Lifetime | 1 hour |
| MFA Required | Yes |