Source/EGU.PartnerPortal.ApiServiceSource/EGU.PartnerPortal.ApiService/Middleware/Handler/ServiceTokenHandler.cs6073ce8b-73f3-4df4-9b80-5e40cdc6965fSource/EGU.PartnerPortal.IntegrationServiceAPI┌─────────────────────────────────────────────────────────────────┐
│ SERVICE-TO-SERVICE AUTHENTICATION FLOW │
└─────────────────────────────────────────────────────────────────┘
┌──────────────────┐
│ ApiService │
│ (Needs to call │
│ Integration) │
└────────┬─────────┘
│
│ Step 1: Make API call
│ (e.g., send XML message)
▼
┌──────────────────────────┐
│ ServiceTokenHandler │
│ (Middleware) │
└────────┬─────────────────┘
│
│ Step 2: Need token first!
│ Request token from Azure AD
│ Sends:
│ - Client ID
│ - Client Secret
│ - Scope
▼
┌──────────────────────────────┐
│ Microsoft Entra ID │
│ Token Endpoint │
└────────┬─────────────────────┘
│
│ Step 3: Azure AD validates
│ ✓ Client ID exists
│ ✓ Client secret matches
│ ✓ Service has permission
▼
┌──────────────────────────────┐
│ Azure AD Returns Token │
│ (for IntegrationServiceAPI) │
└────────┬─────────────────────┘
│
│ Step 4: Token attached to request
│ Authorization: Bearer eyJ...
▼
┌──────────────────────────────┐
│ IntegrationServiceAPI │
│ Validates Token │
└────────┬─────────────────────┘
│
│ Step 5: Token validation
│ ✓ Signature valid
│ ✓ Issuer correct
│ ✓ Audience correct
│ ✓ Not expired
▼
┌──────────────────────────────┐
│ ✅ Process Request │
│ Execute API logic │
│ Return Response │
└──────────────────────────────┘
The authentication works in both directions:
Direction 1: ApiService → IntegrationServiceAPI
Direction 2: IntegrationServiceAPI → ApiService
The authentication flow is identical in both directions:
Only the credentials differ:
| Direction | Client ID (Who's calling) | Client Secret (Who's calling) | Audience (Who's being called) |
|---|---|---|---|
| ApiService → Integration | ApiService ID | ApiService secret | IntegrationServiceAPI ID |
| Integration → ApiService | IntegrationServiceAPI ID | IntegrationServiceAPI secret | ApiService ID |
ApiService calls IntegrationServiceAPI when:
IntegrationServiceAPI calls ApiService when:
Each service authenticates itself when making the call, proving its identity to the other service.
Note: The steps below show ApiService calling IntegrationServiceAPI, but the process is identical in reverse (IntegrationServiceAPI calling ApiService) - just swap the service names and credentials.
What happens:
Who's involved:
Result: