# Swagger Authorization - Simple Guide
## Step-by-Step Process & Entities

---

## Entities Involved

### 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: `/swagger` endpoint (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)
- 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):**
1. Developer selects an endpoint (e.g., `GET /api/v1/WorkOrder/Overview`)
2. Clicks "Try it out"
3. Fills in any required parameters
4. Clicks "Execute"
5. Swagger UI automatically adds the access token to the request
6. 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):**
1. API receives request with token
2. Authentication middleware examines the token
3. Checks who issued the token (Azure AD)
4. 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)
5. If all checks pass → Request continues to controller
6. 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/swagger` or `http://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](swagger-ip-whitelisting.md)

### 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 |

---

## Key Differences: Swagger Auth vs User Auth

| Aspect | Swagger Authorization | User Authentication (Web App) |
|--------|----------------------|------------------------------|
| **Who uses it** | Developers testing APIs | End users accessing the portal |
| **Token refresh** | ❌ No (must re-authorize every hour) | ✅ Yes (automatic, seamless) |
| **Token storage** | Browser memory (cleared on tab close) | sessionStorage (cleared on tab close) |
| **Issuer** | Azure AD | CIAM (External users) |
| **Available in** | Dev/Test/Staging only | All environments |

**Note**: Both use the same Swagger client ID and both require MFA authentication.

---

**Last Updated**: 2025-12-09
