API-Explorer-II/MULTI-OIDC-IMPLEMENTATION-STATUS.md
simonredfern 04cf791f90 Add implementation status document
- Document completed backend implementation
- List remaining frontend and testing tasks
- Include architecture diagrams and data flow
- Document configuration and endpoints
- Track session data structure
- Note backward compatibility approach
2026-01-14 13:00:45 +01:00

12 KiB

Multi-OIDC Provider Implementation Status

Branch: multi-login
Date: 2024
Status: Backend Complete - Frontend In Progress


Overview

This document tracks the implementation status of multiple OIDC provider support in API Explorer II, enabling users to choose from different identity providers (OBP-OIDC, Keycloak, Google, GitHub, etc.) at login time.


Implementation Summary

Completed (Backend)

1. Type Definitions

  • server/types/oauth2.ts
    • WellKnownUri - Provider information from OBP API
    • WellKnownResponse - Response from /obp/v5.1.0/well-known
    • ProviderStrategy - Provider configuration
    • ProviderStatus - Provider health information
    • OIDCConfiguration - OpenID Connect discovery
    • TokenResponse - OAuth2 token response
    • UserInfo - OIDC UserInfo endpoint response

2. Core Services

  • server/services/OAuth2ClientWithConfig.ts

    • Extends arctic OAuth2Client with OIDC discovery
    • Stores provider name and OIDC configuration
    • Methods:
      • initOIDCConfig() - Fetch and validate OIDC discovery document
      • getAuthorizationEndpoint() - Get auth endpoint from config
      • getTokenEndpoint() - Get token endpoint from config
      • getUserInfoEndpoint() - Get userinfo endpoint from config
      • exchangeAuthorizationCode() - Token exchange with PKCE
      • refreshTokens() - Refresh access token
      • isInitialized() - Check if config loaded
  • server/services/OAuth2ProviderFactory.ts

    • Strategy pattern for provider configurations
    • Loads strategies from environment variables
    • Supported providers:
      • OBP-OIDC (VITE_OBP_OAUTH2_*)
      • Keycloak (VITE_KEYCLOAK_*)
      • Google (VITE_GOOGLE_*)
      • GitHub (VITE_GITHUB_*)
      • Custom OIDC (VITE_CUSTOM_OIDC_*)
    • Methods:
      • initializeProvider() - Create and initialize OAuth2 client
      • getConfiguredProviders() - List available strategies
      • hasStrategy() - Check if provider configured
  • server/services/OAuth2ProviderManager.ts

    • Manages multiple OAuth2 providers
    • Fetches well-known URIs from OBP API
    • Tracks provider health status
    • Performs periodic health checks (60s intervals)
    • Methods:
      • fetchWellKnownUris() - Get providers from OBP API
      • initializeProviders() - Initialize all providers
      • getProvider() - Get OAuth2 client by name
      • getAvailableProviders() - List healthy providers
      • getAllProviderStatus() - Get status for all providers
      • startHealthCheck() - Start monitoring
      • stopHealthCheck() - Stop monitoring
      • retryProvider() - Retry failed provider

3. Controllers

  • server/controllers/OAuth2ProvidersController.ts

    • New endpoint: GET /api/oauth2/providers
    • Returns list of available providers with status
    • Used by frontend for provider selection UI
  • server/controllers/OAuth2ConnectController.ts (Updated)

    • Updated: GET /api/oauth2/connect?provider=<name>&redirect=<url>
    • Supports both multi-provider and legacy single-provider mode
    • Multi-provider: Uses provider from query parameter
    • Legacy: Falls back to existing OAuth2Service
    • Generates PKCE parameters (code_verifier, code_challenge, state)
    • Stores provider name in session
    • Redirects to provider's authorization endpoint
  • server/controllers/OAuth2CallbackController.ts (Updated)

    • Updated: GET /api/oauth2/callback?code=<code>&state=<state>
    • Retrieves provider from session
    • Uses correct OAuth2 client for token exchange
    • Validates state (CSRF protection)
    • Exchanges authorization code for tokens
    • Fetches user info from provider
    • Stores tokens and user data in session
    • Supports both multi-provider and legacy modes

4. Server Initialization

  • server/app.ts (Updated)
    • Initialize OAuth2ProviderManager on startup
    • Fetch providers from OBP API
    • Start health monitoring (60s intervals)
    • Register OAuth2ProvidersController
    • Maintain backward compatibility with legacy OAuth2Service

🚧 In Progress (Frontend)

5. Frontend Components

  • src/components/HeaderNav.vue (To be updated)

    • Fetch available providers on mount
    • Display provider selection UI
    • Handle login with selected provider
    • Show provider availability status
  • src/components/ProviderSelector.vue (To be created)

    • Modal/dropdown for provider selection
    • Display provider names and status
    • Trigger login with selected provider
    • Responsive design

📋 Not Started

6. Testing

  • Unit tests for OAuth2ClientWithConfig
  • Unit tests for OAuth2ProviderFactory
  • Unit tests for OAuth2ProviderManager
  • Integration tests for multi-provider flow
  • E2E tests for login flow

7. Documentation

  • Update README.md with multi-provider setup
  • Update OAUTH2-README.md
  • Create migration guide
  • Update deployment documentation

Architecture

Data Flow

1. Server Startup
   ├─> OAuth2ProviderManager.initializeProviders()
   ├─> Fetch well-known URIs from OBP API (/obp/v5.1.0/well-known)
   ├─> For each provider:
   │   ├─> OAuth2ProviderFactory.initializeProvider()
   │   ├─> Create OAuth2ClientWithConfig
   │   ├─> Fetch .well-known/openid-configuration
   │   └─> Store in providers Map
   └─> Start health monitoring (60s intervals)

2. User Login Flow
   ├─> Frontend: Fetch available providers (GET /api/oauth2/providers)
   ├─> User selects provider (e.g., "obp-oidc")
   ├─> Redirect: /api/oauth2/connect?provider=obp-oidc&redirect=/resource-docs
   ├─> OAuth2ConnectController:
   │   ├─> Get OAuth2Client for selected provider
   │   ├─> Generate PKCE (code_verifier, code_challenge, state)
   │   ├─> Store in session (provider, code_verifier, state)
   │   └─> Redirect to provider's authorization endpoint
   ├─> User authenticates on OIDC provider
   ├─> Callback: /api/oauth2/callback?code=xxx&state=yyy
   └─> OAuth2CallbackController:
       ├─> Retrieve provider from session
       ├─> Get OAuth2Client for provider
       ├─> Validate state (CSRF protection)
       ├─> Exchange code for tokens (with PKCE)
       ├─> Fetch user info
       ├─> Store tokens and user in session
       └─> Redirect to original page

3. Health Monitoring
   └─> Every 60 seconds:
       ├─> For each provider:
       │   ├─> HEAD request to issuer endpoint
       │   └─> Update provider status (available/unavailable)
       └─> Frontend can query status via /api/oauth2/providers

Configuration

Environment Variables

# OBP-OIDC Provider (Required for OBP-OIDC)
VITE_OBP_OAUTH2_CLIENT_ID=48ac28e9-9ee3-47fd-8448-69a62764b779
VITE_OBP_OAUTH2_CLIENT_SECRET=fOTQF7jfg8C74u7ZhSjVQpoBYvD0KpWfM5UsEZBSFFM
VITE_OBP_OAUTH2_REDIRECT_URL=http://localhost:5173/api/oauth2/callback

# Keycloak Provider (Optional)
VITE_KEYCLOAK_CLIENT_ID=obp-api-explorer
VITE_KEYCLOAK_CLIENT_SECRET=your-keycloak-secret
VITE_KEYCLOAK_REDIRECT_URL=http://localhost:5173/api/oauth2/callback

# Google Provider (Optional)
# VITE_GOOGLE_CLIENT_ID=your-google-client-id
# VITE_GOOGLE_CLIENT_SECRET=your-google-client-secret
# VITE_GOOGLE_REDIRECT_URL=http://localhost:5173/api/oauth2/callback

# GitHub Provider (Optional)
# VITE_GITHUB_CLIENT_ID=your-github-client-id
# VITE_GITHUB_CLIENT_SECRET=your-github-client-secret
# VITE_GITHUB_REDIRECT_URL=http://localhost:5173/api/oauth2/callback

# Custom OIDC Provider (Optional)
# VITE_CUSTOM_OIDC_PROVIDER_NAME=my-provider
# VITE_CUSTOM_OIDC_CLIENT_ID=your-client-id
# VITE_CUSTOM_OIDC_CLIENT_SECRET=your-client-secret
# VITE_CUSTOM_OIDC_REDIRECT_URL=http://localhost:5173/api/oauth2/callback

# Legacy Single-Provider Mode (Backward Compatibility)
# VITE_OBP_OAUTH2_WELL_KNOWN_URL=http://127.0.0.1:9000/obp-oidc/.well-known/openid-configuration

OBP API Configuration

The multi-provider system fetches available providers from:

GET /obp/v5.1.0/well-known

Expected Response:

{
  "well_known_uris": [
    {
      "provider": "obp-oidc",
      "url": "http://127.0.0.1:9000/obp-oidc/.well-known/openid-configuration"
    },
    {
      "provider": "keycloak",
      "url": "http://127.0.0.1:8180/realms/obp/.well-known/openid-configuration"
    }
  ]
}

Endpoints

New Endpoints

Method Path Description
GET /api/oauth2/providers List available OIDC providers with status

Updated Endpoints

Method Path Query Parameters Description
GET /api/oauth2/connect provider (optional), redirect (optional) Initiate OAuth2 flow with selected provider
GET /api/oauth2/callback code, state, error (optional) Handle OAuth2 callback from any provider

Session Data

Login Initiation

session = {
  oauth2_provider: "obp-oidc",           // Provider name
  oauth2_code_verifier: "...",           // PKCE code verifier
  oauth2_state: "...",                   // CSRF state token
  oauth2_redirect_page: "/resource-docs" // Redirect after auth
}

After Token Exchange

session = {
  oauth2_provider: "obp-oidc",      // Provider used
  oauth2_access_token: "...",       // Access token
  oauth2_refresh_token: "...",      // Refresh token
  oauth2_id_token: "...",           // ID token (JWT)
  user: {
    username: "john.doe",
    email: "john@example.com",
    name: "John Doe",
    provider: "obp-oidc",
    sub: "uuid-1234"
  }
}

Backward Compatibility

The implementation maintains full backward compatibility with the existing single-provider OAuth2 system:

  1. Legacy Environment Variable: VITE_OBP_OAUTH2_WELL_KNOWN_URL still works
  2. Fallback Behavior: If no provider parameter is specified, falls back to legacy OAuth2Service
  3. No Breaking Changes: Existing deployments continue to work without changes
  4. Gradual Migration: Can enable multi-provider incrementally

Benefits

  1. User Choice - Users select their preferred identity provider
  2. Dynamic Discovery - Providers discovered from OBP API automatically
  3. Health Monitoring - Real-time provider availability tracking
  4. Extensibility - Add new providers via environment variables only
  5. Resilience - Fallback to available providers if one fails
  6. Backward Compatible - No breaking changes for existing deployments

Next Steps

Priority 1: Frontend Implementation

  1. Update HeaderNav.vue to fetch and display available providers
  2. Create ProviderSelector.vue component for provider selection
  3. Test login flow with multiple providers
  4. Handle error states gracefully

Priority 2: Testing

  1. Write unit tests for all new services
  2. Create integration tests for multi-provider flow
  3. Add E2E tests for login scenarios

Priority 3: Documentation

  1. Update README.md with setup instructions
  2. Document environment variables for each provider
  3. Create migration guide from single to multi-provider
  4. Update deployment documentation

Known Issues

  • None currently identified

References

  • Implementation Guide: MULTI-OIDC-PROVIDER-IMPLEMENTATION.md
  • Executive Summary: MULTI-OIDC-PROVIDER-SUMMARY.md
  • Flow Diagrams: MULTI-OIDC-FLOW-DIAGRAM.md
  • OBP-Portal Reference: ~/Documents/workspace_2024/OBP-Portal
  • Branch: multi-login

Commits

  1. 3dadca8 - Add multi-OIDC provider backend services
  2. 8b90bb4 - Add multi-OIDC provider controllers and update app initialization
  3. 755dc70 - Fix TypeScript compilation errors in multi-provider implementation

Last Updated: 2024
Status: Backend implementation complete