/swagger endpoint (e.g., http://localhost:7532/swagger)6073ce8b-73f3-4df4-9b80-5e40cdc6965f84c38b43-12e4-4c26-8292-8910d79aa532Source/EGU.PartnerPortal.ApiServicehttp://localhost:7532/swagger (local)4dad5d62-dc8c-4378-8bd0-ae736a4d73feapi://4dad5d62-dc8c-4378-8bd0-ae736a4d73fe/access_as_userSource/EGU.PartnerPortal.IntegrationServiceAPIhttp://localhost:7098/swagger (local)bd5100ee-af63-4880-8c60-47d4207d60c1api://bd5100ee-af63-4880-8c60-47d4207d60c1/access_as_user┌─────────────────────────────────────────────────────────────────┐
│ 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 │
└────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐ │ 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 │ └──────────────┘ └──────────────┘ └──────────────┘
What happens:
http://localhost:7532/swagger (local dev)http://localhost:7098/swagger (local dev)Who's involved:
What you see:
Result:
What happens:
Who's involved:
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:
What happens:
Who's involved:
What's sent to Microsoft:
Result:
What happens:
developer@example.com)Who's involved:
What Microsoft validates:
Result:
What happens:
Who's involved:
Result:
What happens:
Who's involved:
What's in the access token:
Result:
What happens (every time developer tests an endpoint):
GET /api/v1/WorkOrder/Overview)Who's involved:
Result:
What happens (on ApiService/IntegrationServiceAPI):
Who's involved:
What's validated:
Result:
Swagger UI access varies by environment for security:
http://localhost:7532/swagger or http://localhost:7098/swaggerPurpose: Proves developer is authenticated and authorized to call API endpoints
Lifetime: 1 hour
What's in the token:
When token expires:
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
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
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
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
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