IDP Client-Side Implementation Overview (Version 2)¶
Introduction¶
The client-side IDP implementation provides device registration, token management, and authentication for Angular applications using NGXS state management. This implementation supports two OAuth2 authentication flows with platform-specific service implementations:
- Client Credentials Grant (
client_credentials): OTP-based device registration with client_id/client_secret authentication - JWT Bearer Assertion Grant (
jwt-bearer): Certificate-based authentication using X.509 client certificates
The architecture centralizes authentication state, coordinates cross-module integration, and provides a robust foundation for both credential-based and certificate-based authentication flows across web, Capacitor (iOS/Android), and Electron environments.
Architecture Overview¶
┌─────────────────────┐ ┌──────────────────┐ ┌─────────────────────┐
│ NGXS State │ │ Component │ │ Federated │
│ Management │───►│ Layer │───►│ Service Layer │
└─────────────────────┘ └──────────────────┘ └─────────────────────┘
│ │ │
├─ Centralized State ├─ User Interface ├─ Platform Detection
├─ Action Dispatching ├─ Form Management ├─ Service Federation
├─ Side Effects ├─ Error Handling ├─ OAuth2 Flow
└─ Cross-Module Coord └─ Navigation Flow └─ Token Caching
│
┌───────┼───────┐
│ │ │
┌─────────┐ ┌──────┐ ┌─────────┐
│ Web │ │ Cap. │ │Electron │
│ Service │ │Plugin│ │ Plugin │
└─────────┘ └──────┘ └─────────┘
Core Architecture Components¶
1. State Management Layer (idp.state.ts)¶
The IDP state management provides centralized control over authentication flow and coordinates with other application modules:
Action Handlers:¶
Token Management Actions:
- ResetToken: Clears authentication token from application state
- SetToken: Updates state with new access token and expiration information
- ResetClientCredentials: Removes stored client credentials via service layer
Authentication Orchestration:
- IdpAuthenticate: Orchestrates the complete authentication flow:
1. Calls federated service to retrieve access token using stored client credentials
2. Parses JWT token to extract device and server configuration claims
3. Creates provisioning data structure with device metadata from JWT
4. Dispatches provisioning initialization with extracted configuration
5. Triggers bootstrap initialization with authenticated server URL from JWT claims
2. Federated Service Layer (federated-idp-access-token.service.ts)¶
The federated service acts as a platform-aware facade that automatically detects the runtime environment and loads the appropriate IDP implementation:
Platform Detection Logic:¶
- Electron Detection: Checks for
window.openposElectronAPI - Capacitor Detection: Checks for
window.Capacitor.isNativePlatform() - Web Fallback: Defaults to web implementation for browser environments
Service Loading Strategy:¶
- Electron: Loads
ElectronIdpAccessTokenServicedirectly from bootstrap module - Web/Capacitor: Uses module federation to load remote IDP service from federated modules
3. Platform-Specific Service Implementations¶
Web Service (web-idp-access-token.service.ts)¶
- Local Storage: Uses browser localStorage for credential persistence
- Fetch API: Standard HTTP requests for OAuth2 operations
- Token Caching: In-memory and localStorage token caching with expiration validation
- Encryption: Base64 encoding for basic credential protection
Capacitor Plugin (idp-access-token.service.ts + Native Plugins)¶
- Secure Storage: Platform-native secure storage (Keychain/Keystore)
- Native HTTP: Uses Capacitor's native HTTP capabilities
- Token Caching: Encrypted token storage with platform security
- Cross-Platform: Unified interface for iOS and Android implementations
Electron Service (electron-idp-access-token.service.ts)¶
- IPC Communication: Uses Electron's IPC to communicate with main process
- Main Process Implementation: JWT Bearer assertion and client credentials in main process
- Secure Storage: Electron's safeStorage API for credential encryption
- Token Management: Automatic token caching and refresh in main process
4. Component Architecture (device-registration.component.ts)¶
The device registration component provides the user interface for OTP-based device activation:
User Interface Logic:¶
User Interaction Flow: - Registration Process: Collects user input and triggers device registration through service layer - Error Feedback: Visual error indication with retry capabilities - Skip Functionality: Alternative flow for manual device configuration - State Coordination: Dispatches authentication actions upon successful registration
5. Module Federation Strategy¶
The client-v2 implementation uses Angular's module federation for dynamic service loading:
Federation Configuration:¶
- Manifest Loading: Loads
bootstrap-federation.manifest.jsonfor remote module configuration - Remote Module: IDP functionality loaded as federated remote module
loadRemoteModule('idp', './Idp') - Service Resolution: Dynamic service instantiation based on federated module exports
Client Credentials OAuth2 Flow¶
Grant Type Implementation¶
All platform implementations use the OAuth2 Client Credentials Grant (grant_type=client_credentials) for device authentication:
Flow Characteristics:¶
- Device-Based Authentication: Each device receives unique client credentials (client_id, client_secret)
- OTP Registration: One-time password (OTP) based device registration with IDP service
- Token Endpoint: Device-specific token endpoint provided during registration
- Scope:
devicescope for device-level access permissions
Token Caching Strategy:¶
- Automatic Caching: Tokens cached automatically upon acquisition
- Expiration Validation: 5-minute refresh threshold before token expiry
- Platform Storage: Encrypted storage using platform-specific secure storage
- Cache Invalidation: Automatic cache clearing on credential reset
JWT Bearer Assertion OAuth2 Flow¶
Grant Type Implementation¶
Capacitor and Electron platforms support an alternative OAuth2 JWT Bearer Assertion Grant (grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer) for certificate-based device authentication:
Flow Characteristics:¶
- Certificate-Based Authentication: Uses client certificates (X.509) for device identity
- Self-Signed JWT: Device creates and signs JWT assertions using private key
- No Device Registration: Certificates pre-provisioned, eliminating OTP registration step
- Enhanced Security: PKI-based authentication with certificate chain validation
JWT Assertion Structure¶
JWT Header:¶
{
"alg": "RS256", // RSA-SHA256 or ES256 for EC keys
"typ": "JWT",
"x5c": ["cert1", "cert2"] // X.509 certificate chain (Base64 encoded)
}
JWT Claims:¶
{
"iss": "client", // Issuer (fixed value)
"sub": "device_id", // Subject (device identifier)
"aud": "https://idp.server/token", // Audience (token endpoint)
"iat": 1640995200, // Issued at timestamp
"exp": 1640998800, // Expiration (5 minutes from iat)
"scope": "device" // Requested scope
}
Platform-Specific Implementation¶
Android Implementation (JwtAssertionBuilder.java)¶
Certificate Management: - Android KeyChain API: Accesses device-installed client certificates - Certificate Alias: Configurable alias for certificate selection (default: "commerce") - Automatic Algorithm Detection: Supports RSA (RS256) and EC (ES256) key algorithms - Certificate Chain: Full X.509 certificate chain included in JWT header
Electron Implementation (JwtBearerAssertionService.js)¶
Certificate Management: - File-Based Certificates: Loads certificates from local file system - PEM Format Support: Standard PEM-encoded private keys and certificate chains - Configurable Paths: Certificate and private key file paths via configuration - Automatic Key Detection: Supports RSA and EC private keys
Configuration Requirements¶
Android Configuration (via Android Device Policy/MDM):¶
{
"grant_type": "jwt-bearer",
"cert_alias": "commerce",
"device_id": "unique-device-identifier",
"token_endpoint": "https://idp.server/oauth2/token"
}
Electron Configuration (electron-config.json):¶
{
"activeClient": "jwt-bearer",
"algorithm": "RS256",
"certificateChainFileName": "device.chain.crt",
"privateKeyFileName": "device.key",
"tokenUrl": "https://idp.server/oauth2/token",
"assertionSubject": "device-identifier",
"assertionAudience": "https://idp.server",
"assertionIssuer": "client",
"assertionScope": "device"
}
Security Considerations¶
Certificate Security:¶
- Private Key Protection: Private keys stored in platform secure storage (Android KeyChain, Electron safeStorage)
- Certificate Validation: Server validates certificate chain and signature
- Key Rotation: Supports certificate renewal and key rotation processes
JWT Security:¶
- Signature Verification: Server verifies JWT signature using certificate public key
- Certificate Chain Validation: Full X.509 certificate chain validation including root CA
Integration Components¶
1. HTTP Authentication Interceptor (auth.interceptor.ts)¶
The authentication interceptor provides transparent JWT token management for HTTP requests:
Interceptor Logic Flow:¶
- State Selection: Retrieves current IDP state for immediate access token availability
- Token Validation: Validates token existence and expiration status
- Header Injection: Adds Bearer authorization headers to authenticated requests
- Conditional Processing: Skips authentication for requests when no token available
2. WebSocket Connection Integration (personalization-listener.service.ts)¶
Coordinates authentication state with WebSocket connection headers:
Header Coordination:¶
- State Monitoring: Watches IDP state for
accessTokenchanges - Header Updates: Dispatches
SharedConnectHeadersactions with Bearer tokens - Real-time Sync: Maintains WebSocket authentication in sync with token state
Platform-Specific Implementation Details¶
Shared Service Interface:¶
export interface IdpAccessTokenService {
grantType(): Promise<GrantType>; // Returns "client-credentials" or "jwt-bearer"
registerDevice(options: { otp: string }): Promise<void>; // Only for client-credentials
getAccessToken(): Promise<TokenResponse | null>;
getPrincipal(): Promise<JwtPayload | null>;
resetDevice(): Promise<void>;
}
Grant Type Enumeration:¶
type GrantType = "client-credentials" | "jwt-bearer";
Token Management:¶
interface TokenResponse {
access_token: string;
token_type: string;
expires_in: number;
scope?: string;
}
1. Web Implementation (web-idp-access-token.service.ts)¶
Storage Strategy:¶
- Client Credentials: Base64 encoded in localStorage with key
idp_client_credentials - Access Tokens: Cached in localStorage with expiration tracking
- Encryption: Simple Base64 encoding (sufficient for demo/dev environments)
HTTP Operations:¶
- Fetch API: Standard browser fetch for OAuth2 operations
- CORS Handling: Configured for cross-origin IDP service requests
- Error Handling: Network error detection and user-friendly error messages
2. Capacitor Implementation (iOS/Android Plugins)¶
iOS Plugin (IdpAccessTokenPlugin.swift)¶
- Secure Storage: iOS UserDefaults with automatic encryption
- Network Operations: URLSession for HTTP requests with proper error handling
- Token Caching: Encrypted token storage with 5-minute refresh threshold
- JWT Decoding: Native Base64 decoding for JWT payload extraction
Android Plugin (IdpAccessTokenPlugin.java)¶
- Grant Type Support: Both client credentials and JWT Bearer assertion flows
- Configuration Detection: Automatically selects grant type via Android Device Policy (
grant_typesetting) - Certificate Management:
- Android KeyChain API: Accesses client certificates for JWT Bearer assertions
- Certificate Alias: Configurable certificate selection (default: "commerce")
- Algorithm Support: Automatic detection of RSA (RS256) and EC (ES256) keys
- Secure Storage: Android SecureSharedPreferences with Keystore encryption
- Network Operations: Android HTTP client with SSL/TLS validation
- Token Caching: Keystore-backed secure token storage
- JWT Processing:
- JWT Creation: Nimbus JOSE library for JWT Bearer assertion creation
- Certificate Chain: Full X.509 certificate chain inclusion in JWT header
- Token Parsing: Android Base64 utilities for access token processing
3. Electron Implementation (electron-idp-access-token.service.ts)¶
Architecture:¶
- Grant Type Support: Both client credentials and JWT Bearer assertion flows
- Service Selection: Configuration-driven selection via
activeClientsetting - Renderer Process: Service interface using IPC communication
- Main Process: Full OAuth2 implementation with crypto operations
- IPC Communication: Secure communication between renderer and main processes
Main Process Services:¶
- ClientCredentialsService:
- Full client credentials OAuth2 flow with OTP device registration
- Encrypted credential storage using Electron's safeStorage API
- Automatic token caching with expiration validation
- JwtBearerAssertionService:
- Certificate-based JWT Bearer assertion flow
- File-Based Certificates: PEM-encoded certificate and private key loading
- JWT Creation: jose library for standards-compliant JWT generation
- Certificate Chain: X.509 certificate chain embedding in JWT header
- Configurable Claims: Audience, issuer, subject, and scope configuration
- Token Caching:
- Unified TokenCache implementation for both grant types
- Encrypted storage using Electron's safeStorage API