{"id":31037245,"url":"https://github.com/openbankproject/obp-oidc","last_synced_at":"2026-01-20T17:39:36.553Z","repository":{"id":310979353,"uuid":"1041834781","full_name":"OpenBankProject/OBP-OIDC","owner":"OpenBankProject","description":"A simple Open ID Connect server for use by developers who want to work with the various Apps in the OBP ecosystem.","archived":false,"fork":false,"pushed_at":"2025-09-09T10:39:44.000Z","size":260,"stargazers_count":0,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-09T13:30:01.793Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenBankProject.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-21T04:48:38.000Z","updated_at":"2025-09-09T10:39:47.000Z","dependencies_parsed_at":"2025-08-21T12:21:51.109Z","dependency_job_id":"e2766170-5031-40c1-980d-0bf45d787cf9","html_url":"https://github.com/OpenBankProject/OBP-OIDC","commit_stats":null,"previous_names":["openbankproject/obp-oidc"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/OpenBankProject/OBP-OIDC","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenBankProject%2FOBP-OIDC","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenBankProject%2FOBP-OIDC/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenBankProject%2FOBP-OIDC/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenBankProject%2FOBP-OIDC/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenBankProject","download_url":"https://codeload.github.com/OpenBankProject/OBP-OIDC/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenBankProject%2FOBP-OIDC/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275062961,"owners_count":25398887,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-14T02:00:10.474Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-09-14T04:56:21.856Z","updated_at":"2026-01-20T17:39:36.515Z","avatar_url":"https://github.com/OpenBankProject.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OBP-OIDC\n\n# TLDR;\n\nThis is a bare bones OpenID Connect (OIDC) provider built with http4s and functional programming in Scala.\n\nThis implementation follows the same technology stack as OBP-API-II and integrates with PostgreSQL database for real user authentication.\n\nIt's meant to be used with OBP-API and apps such as the OBP Portal by developers.\n\n**For External Access**: To run behind a TLS terminating proxy with HTTPS URLs, set `OIDC_EXTERNAL_URL` environment variable:\n\n```bash\nexport OIDC_EXTERNAL_URL=\"https://oidc.yourdomain.com\"\n./run-server.sh\n```\n\nIts not a production grade OIDC server. For that use Keyclock or Hydra etc.\n\nIf you're having trouble understanding OIDC with OBP this tool might help.\n\nDesigned to create clients for the OBP Apps as it starts up. It will print client_id, secrets and other info so you can copy and paste into your Props or env files.\n\nDesigned to read / write to the OBP Users and Consumers tables via SQL views defined in [OBP-API](https://github.com/OpenBankProject/OBP-API/blob/develop/obp-api/src/main/scripts/sql/create_oidc_user_and_views.sql)\n\n### 1. Create OIDC Database Users and Views\n\nThis application assumes you have an OBP database running locally.\n\nThe following script in OBP-API will create the SQL roles and views (2 or 3 of them) that this application needs to work.\n\nhttps://github.com/OpenBankProject/OBP-API/blob/develop/obp-api/src/main/scripts/sql/create_oidc_user_and_views.sql\n\nIf you have OBP source code locally you can run the file thus:\n\n```bash\npsql -h localhost -p 5432 -d sandbox -U obp -f workspace_2024/OBP-API-C/OBP-API/obp-api/src/main/scripts/sql/create_oidc_user_and_views.sql\n```\n\nor from with in psql thus\n\n```psql\n\n\\i PATH-TO-OBP-API-SOURCE-CODE/obp-api/src/main/scripts/sql/create_oidc_user_and_views.sql\n\n```\n\n### Step 2: Make sure your passwords are good.\n\n# Copy the example run server script\n\n#\n\n```bash\n\ncp ./run-server.example.sh ./run-server.sh\n\n```\n\nMaybe this involves an export\n\n```bash\n# Export the generated environment variables\nexport OIDC_USER_PASSWORD=YourGeneratedPassword123!\nexport OIDC_ADMIN_PASSWORD=YourGeneratedAdminPass456#\n# ... (other exports from generated config)\n\n```\n\nNow you can try and run the server\n\n```bash\n\n./run-server.sh\n\n```\n\nNOTE: you should make sure the OBP-API well known url returns the OBP-OIDC address.\n\n**That's it!** 🎉 Copy the printed OIDC client configurations to your OBP projects.\n\n# The long story.\n\n## Prerequisites\n\n- Java 11 or higher\n- Maven 3.6+\n- PostgreSQL database with OBP schema\n- OBP authuser table with validated users\n\n## Database Setup\n\n### 1. PostgreSQL Database\n\nEnsure you have a PostgreSQL database with the OBP authuser table populated with users.\n\nSee above.\n\n### 3. Database Configuration\n\nSet environment variables for database connection:\n\n**Read-Only Database User** (for user authentication):\n\nSee the sql script.\n\n### Build and Run\n\n1. **Compile the project:**\n\n   ```bash\n   mvn clean compile\n   ```\n\n2. **Run the server:**\n\n   ```bash\n   mvn exec:java -Dexec.mainClass=\"com.tesobe.oidc.server.OidcServer\"\n   ```\n\n3. **The server starts on http://localhost:9000** and automatically:\n   - Creates OIDC clients for OBP-API, Portal, Explorer II, and Opey II\n   - Prints complete client configurations for easy integration\n   - Tests all database connections\n\n### Using the Run Script (Recommended)\n\nFor easier configuration and running:\n\n1. **Copy the example script:**\n\n   ```bash\n   cp run-server.example.sh run-server.sh\n   ```\n\n2. **Edit your database credentials:**\n\n   ```bash\n   vim run-server.sh\n   # Edit the DB_* environment variables with your actual database settings\n   ```\n\n3. **Make it executable and run:**\n   ```bash\n   chmod +x run-server.sh\n   ./run-server.sh\n   ```\n\nThe script will:\n\n- ✅ Set all necessary environment variables\n- ✅ Build the project\n- ✅ Start the server with helpful output\n- ✅ Show available endpoint URLs\n- ✅ Print ready-to-use OBP-API configuration\n\n### Server Configuration\n\n#### Port Configuration\n\nThe server runs on port **9000** by default. You can change this by setting the `OIDC_PORT` environment variable:\n\n```bash\n# Run on default port 9000\nmvn exec:java -Dexec.mainClass=\"com.tesobe.oidc.server.OidcServer\"\n\n# Run on custom port (e.g., 8080)\nexport OIDC_PORT=8080\nmvn exec:java -Dexec.mainClass=\"com.tesobe.oidc.server.OidcServer\"\n\n# Or set inline\nOIDC_PORT=8080 mvn exec:java -Dexec.mainClass=\"com.tesobe.oidc.server.OidcServer\"\n```\n\n### Discovery Document\n\n```\nGET /.well-known/openid-configuration\n```\n\nReturns the OIDC discovery document with all endpoint URLs and supported features.\n\n### Authorization Endpoint\n\n```\nGET /auth?response_type=code\u0026client_id=YOUR_CLIENT\u0026redirect_uri=YOUR_REDIRECT\u0026scope=openid%20profile%20email\u0026state=ABC123\n```\n\nShows HTML login form for user authentication. Supports authorization code flow.\n\n### Token Endpoint\n\n```\nPOST /token\nContent-Type: application/x-www-form-urlencoded\n\ngrant_type=authorization_code\u0026code=AUTH_CODE\u0026redirect_uri=YOUR_REDIRECT\u0026client_id=YOUR_CLIENT\n```\n\nExchanges authorization code for ID token and access token.\n\n### UserInfo Endpoint\n\n```\nGET /userinfo\nAuthorization: Bearer ACCESS_TOKEN\n```\n\nReturns user claims based on token scope.\n\n### JWKS Endpoint\n\n```\nGET /jwks\n```\n\nReturns JSON Web Key Set for token verification.\n\n## Testing the Server\n\n### Quick Health Check\n\nOnce the server is running, test it with these curl commands:\n\n```bash\n# Health check\ncurl -v http://localhost:9000/health\n# Expected: \"OIDC Provider is running\"\n\n# Root welcome page\ncurl -v http://localhost:9000/\n# Expected: HTML page with endpoint documentation\n```\n\n### OIDC Discovery Document ⭐\n\nThis is the standard OIDC well-known URL that clients use to discover your service:\n\n```bash\ncurl http://localhost:9000/.well-known/openid-configuration\n```\n\n**Expected JSON response:**\n\n```json\n{\n  \"issuer\": \"http://localhost:9000\",\n  \"authorization_endpoint\": \"http://localhost:9000/auth\",\n  \"token_endpoint\": \"http://localhost:9000/token\",\n  \"userinfo_endpoint\": \"http://localhost:9000/userinfo\",\n  \"jwks_uri\": \"http://localhost:9000/jwks\",\n  \"response_types_supported\": [\"code\"],\n  \"subject_types_supported\": [\"public\"],\n  \"id_token_signing_alg_values_supported\": [\"RS256\"],\n  \"scopes_supported\": [\"openid\", \"profile\", \"email\"],\n  \"token_endpoint_auth_methods_supported\": [\"client_secret_post\"],\n  \"claims_supported\": [\"sub\", \"name\", \"email\", \"email_verified\"]\n}\n```\n\n### JSON Web Key Set (JWKS)\n\n```bash\ncurl http://localhost:9000/jwks\n```\n\n**Expected JSON response:**\n\n```json\n{\n  \"keys\": [\n    {\n      \"kty\": \"RSA\",\n      \"use\": \"sig\",\n      \"alg\": \"RS256\",\n      \"kid\": \"your-key-id\",\n      \"n\": \"...\",\n      \"e\": \"AQAB\"\n    }\n  ]\n}\n```\n\n### Authorization Endpoint (Login Form)\n\n```bash\ncurl \"http://localhost:9000/auth?response_type=code\u0026client_id=test-client\u0026redirect_uri=https://example.com/callback\u0026scope=openid%20profile%20email\u0026state=test123\"\n```\n\n**Expected:** HTML login form\n\n### Browser Testing\n\nOpen these URLs in your browser:\n\n- **Welcome Page**: `http://localhost:9000/`\n- **Discovery**: `http://localhost:9000/.well-known/openid-configuration`\n- **JWKS**: `http://localhost:9000/jwks`\n- **Login Form**: `http://localhost:9000/auth?response_type=code\u0026client_id=test-client\u0026redirect_uri=https://example.com/callback\u0026scope=openid\u0026state=test123`\n\n## Authentication\n\n### Database Views\n\nThis OIDC provider uses three PostgreSQL database views:\n\n#### User Authentication (`v_oidc_users`)\n\n- Authenticates users from the validated authuser table\n- BCrypt password verification\n- User profile information (name, email)\n\n#### Client Registration (`v_oidc_clients`)\n\n- Validates registered OIDC clients\n- Controls allowed redirect URIs\n- Manages client permissions and scopes\n\n#### Client Management (`v_oidc_admin_clients`)\n\n- Provides write access for client administration\n- Used by admin database user for CRUD operations\n- Supports creating, updating, and deleting OIDC clients\n\n### Supported Database Fields\n\n#### User Fields (`v_oidc_users` view)\n\n- `user_id`: Internal unique identifier\n- `username`: Login identifier, used as OIDC subject (`sub`) claim for OBP-API compatibility\n- `firstname`, `lastname`: User's full name\n- `email`: User's email address\n- `provider`: Authentication provider, used as OIDC issuer (`iss`) claim for OBP-API compatibility\n- `validated`: Must be true for authentication\n\n#### Client Fields (`v_oidc_clients` and `v_oidc_admin_clients` views)\n\n- `client_id`: Unique client identifier\n- `client_secret`: Client authentication secret\n- `client_name`: Human-readable client name\n- `redirect_uris`: Comma-separated list of allowed redirect URIs\n- `grant_types`: Supported OAuth2 grant types\n- `response_types`: Supported OAuth2 response types\n- `scopes`: Available OAuth2 scopes\n- `token_endpoint_auth_method`: Client authentication method\n- `created_at`: Client registration timestamp\n- `password_pw`: BCrypt password hash\n- `password_slt`: Password salt for verification\n\n#### Client Fields (`v_oidc_clients` view)\n\n- `client_id`: Unique client identifier\n- `client_secret`: Secret for confidential clients (optional)\n- `client_name`: Human-readable application name\n- `redirect_uris`: JSON array of allowed callback URLs\n- `grant_types`: Supported OAuth2 grant types (default: authorization_code)\n- `scopes`: Allowed access scopes (default: openid, profile, email)\n- `token_endpoint_auth_method`: Client authentication method\n\n## OBP-API Integration\n\n### JWT Token Claims\n\nFor compatibility with OBP-API, JWT tokens are generated with specific claim mappings from the `v_oidc_users` database view:\n\n- **`sub` (Subject)**: Contains the user's `username` field from `v_oidc_users`\n  - Source: `v_oidc_users.username`\n  - Purpose: OBP-API uses this to identify the user\n- **`iss` (Issuer)**: Contains the user's `provider` field from `v_oidc_users`\n  - Source: `v_oidc_users.provider`\n  - Purpose: OBP-API uses this to identify the authentication provider\n- **Standard claims**: Populated from user data in `v_oidc_users`\n  - `name`: Combined from `v_oidc_users.firstname` and `v_oidc_users.lastname`\n  - `email`: From `v_oidc_users.email`\n  - `email_verified`: From `v_oidc_users.validated`\n\nThis ensures that OBP-API can correctly identify users using the `sub` field as username and `iss` field as provider, exactly as required for proper integration.\n\n### Token Validation\n\nThe OIDC server accepts tokens with various provider-based issuers, providing flexibility for different authentication providers while maintaining security.\n\n## Example OIDC Flow\n\n1. **Authorization Request:**\n\n   ```\n   http://localhost:9000/auth?response_type=code\u0026client_id=test-client\u0026redirect_uri=https://example.com/callback\u0026scope=openid%20profile%20email\u0026state=abc123\n   ```\n\n2. **User Login:** Enter valid database user credentials\n\n3. **Authorization Code:** Redirected to your callback URL with code parameter\n\n4. **Token Exchange:**\n\n   ```bash\n   curl -X POST http://localhost:9000/token \\\n     -H \"Content-Type: application/x-www-form-urlencoded\" \\\n     -d \"grant_type=authorization_code\u0026code=YOUR_CODE\u0026redirect_uri=https://example.com/callback\u0026client_id=test-client\"\n   ```\n\n5. **UserInfo Request:**\n   ```bash\n   curl http://localhost:9000/userinfo \\\n     -H \"Authorization: Bearer YOUR_ACCESS_TOKEN\"\n   ```\n\n## Testing\n\n### Database Connection Test\n\nThe server will test the database connection on startup and log the results.\n\n### Integration Tests\n\nRun the test suite:\n\n```bash\nmvn test\n```\n\nThe tests demonstrate:\n\n- Discovery document validation\n- JWKS endpoint functionality\n- Authorization flow with login forms\n- Token generation and validation\n- UserInfo endpoint with Bearer tokens\n- Complete end-to-end OIDC flow\n\n## Development\n\n### Project Structure\n\n```\nsrc/main/scala/com/tesobe/oidc/\n├── server/           # Main server setup\n├── endpoints/        # OIDC endpoint implementations\n├── auth/            # Database authentication service\n├── tokens/          # JWT token handling\n├── models/          # Data models with Circe JSON support\n└── config/          # Configuration management\n```\n\n### Key Components\n\n- **DatabaseAuthService**: PostgreSQL-based user authentication\n- **JwtService**: JWT token generation and validation with RSA256\n- **CodeService**: Authorization code management with expiration\n- **Endpoints**: Individual OIDC endpoint implementations\n- **OidcServer**: Main application with http4s routing\n\n### Database Integration\n\n- **Doobie**: Functional database access with connection pooling\n- **HikariCP**: Connection pool management with proper timeouts\n\n### Client Management\n\n- **Automatic Bootstrap**: Creates standard OBP ecosystem clients on startup\n- **Environment Configuration**: Fully customizable via environment variables\n- **Secure Secret Generation**: Auto-generates cryptographically secure client secrets\n- **Update Detection**: Intelligently updates clients when configuration changes\n- **BCrypt**: Password verification compatible with OBP-API\n- **Read-only Access**: Uses dedicated `oidc_user` with minimal permissions\n\n#### Adding New Startup Clients\n\nTo add a new client that gets automatically created during server startup:\n\n1. **Edit the ClientBootstrap.scala file:**\n\n   ```\n   OBP-OIDC/src/main/scala/com/tesobe/oidc/bootstrap/ClientBootstrap.scala\n   ```\n\n2. **Add your client definition to the `CLIENT_DEFINITIONS` list:**\n\n   ```scala\n   ClientDefinition(\n     name = \"your-new-client-id\",\n     redirect_uris = \"http://localhost:PORT/callback,http://localhost:PORT/oauth/callback\"\n   )\n   ```\n\n3. **Restart the server** - Your new client will be automatically created and its configuration printed to the console for integration with your application.\n\n**Example:** The existing `obp-opey-ii-client` is defined as:\n\n```scala\nClientDefinition(\n  name = \"obp-opey-ii-client\",\n  redirect_uris = \"http://localhost:5000/callback,http://localhost:5000/oauth/callback\"\n)\n```\n\n### Functional Programming Principles\n\n- Pure functions where possible\n- Cats Effect IO for side effects\n- Immutable data structures\n- Monadic error handling with Either types\n- Thread-safe database access with connection pooling\n\n## Security Considerations\n\n- Database user has read-only access to validated users only\n- BCrypt password verification with proper salt handling\n- Connection pooling with leak detection and timeouts\n- SSL/TLS preference for database connections\n- Comprehensive logging for security monitoring\n- No password storage in memory beyond verification\n\n## Database Callback URL Fix\n\n### Issue: Wrong Callback URL in Database\n\nIf you encounter redirect issues where the system redirects to `http://localhost:8080/oauth/callback` instead of `http://localhost:8080/auth/openid-connect/callback`, you need to update the database record.\n\n**Root Cause:** The `consumer` table stores the client's `redirecturl` field, which may have been set incorrectly during initial client creation.\n\n**Fix Steps:**\n\n1. **Run the SQL fix script:**\n\n   ```bash\n   psql -d sandbox -f fix-callback-url.sql\n   ```\n\n2. **Or manually update via SQL:**\n\n   ```sql\n   UPDATE consumer\n   SET redirecturl = 'http://localhost:8080/auth/openid-connect/callback'\n   WHERE consumerid = 'obp-api-client';\n   ```\n\n3. **Verify the fix:**\n   ```sql\n   SELECT consumerid, name, redirecturl FROM consumer WHERE consumerid = 'obp-api-client';\n   ```\n\n**Expected Output:**\n\n```\n client_id    | client_name           | redirecturl\n--------------+-----------------------+------------------------------------------------\n obp-api-client| OBP-API Core Service | http://localhost:8080/auth/openid-connect/callback\n```\n\nThis ensures the OAuth authorization flow redirects to the correct OBP-API endpoint.\n\n## Password Verification Fix\n\n### Issue Resolution - OBP-API Password Hash Compatibility\n\n**Problem:** OBP-OIDC was unable to verify passwords hashed by OBP-API due to incompatible BCrypt format handling.\n\n**Root Cause:** OBP-API uses Lift framework's MegaProtoUser which stores BCrypt hashes in a custom format:\n\n- Format: `password_pw = \"b;\" + BCrypt.hashpw(password, salt).substring(0, 44)`\n- The \"b;\" prefix indicates BCrypt format\n- Hash is truncated to 44 characters\n- Salt is stored separately in `password_slt` field\n\n**Solution Implemented:**\n\n1. **Added jBCrypt dependency** (same library used by OBP-API):\n\n   ```xml\n   \u003cdependency\u003e\n     \u003cgroupId\u003eorg.mindrot\u003c/groupId\u003e\n     \u003cartifactId\u003ejbcrypt\u003c/artifactId\u003e\n     \u003cversion\u003e0.4\u003c/version\u003e\n   \u003c/dependency\u003e\n   ```\n\n2. **Updated password verification logic** in `DatabaseAuthService.scala`:\n\n   ```scala\n   if (storedHash.startsWith(\"b;\")) {\n     val hashWithoutPrefix = storedHash.substring(2) // Remove \"b;\" prefix\n     val generatedHash = JBCrypt.hashpw(plainPassword, salt).substring(0, 44)\n     val isMatch = generatedHash == hashWithoutPrefix\n   }\n   ```\n\n3. **Database view compatibility** - Uses existing `v_oidc_users` view fields:\n   - `password_pw` - Contains \"b;\" + truncated hash\n   - `password_slt` - Contains BCrypt salt\n\n**Verification Process:**\n\n1. Detect \"b;\" prefix format\n2. Extract hash without prefix\n3. Generate hash using `JBCrypt.hashpw(password, salt)`\n4. Truncate to 44 characters\n5. Compare with stored hash\n\n**Testing:**\n\n- Use `test-password-verification.scala` to validate implementation\n- Comprehensive debug logging added for troubleshooting\n- Character-by-character comparison for failed attempts\n\nThis fix ensures 100% compatibility with OBP-API password verification.\n\n## Troubleshooting\n\n### Server Startup Hanging\n\nIf the server hangs during startup (especially after showing \"🚀 Initializing OBP ecosystem OIDC clients...\"):\n\n1. **Admin Database Issues**: The server may be waiting for admin database connection\n\n   ```bash\n   # Check if admin database user exists and has permissions\n   ./test-admin-db.sh\n   ```\n\n2. **Quick Fix**: The server has built-in timeouts (15 seconds) and will continue startup\n   - Wait up to 30 seconds for automatic recovery\n   - Look for timeout warnings in logs\n   - Server will provide manual SQL commands if admin DB unavailable\n\n3. **Manual Client Creation**: If admin database unavailable, copy SQL from server logs:\n\n   ```sql\n   INSERT INTO v_oidc_admin_clients (client_id, client_secret, client_name, ...)\n   VALUES ('obp-api-client', 'your-secret', 'OBP-API', ...);\n   ```\n\n4. **Disable Client Bootstrap**: Set environment variable to skip:\n   ```bash\n   export OIDC_SKIP_CLIENT_BOOTSTRAP=true\n   ```\n\n### Database Connection Issues\n\n1. Verify PostgreSQL is running and accessible\n2. Check database credentials and permissions:\n   - `OIDC_USER_USERNAME` and `OIDC_USER_PASSWORD` for read-only access\n   - `OIDC_ADMIN_USERNAME` and `OIDC_ADMIN_PASSWORD` for client management\n3. Ensure database views exist:\n   - `v_oidc_users` for user authentication\n   - `v_oidc_clients` for client validation\n   - `v_oidc_admin_clients` for client management (optional)\n4. Review database logs for connection errors\n\n### Authentication Failures\n\n1. Verify user exists and is validated in authuser table\n2. Check password hash format - should start with \"b;\" for OBP-API compatibility\n3. Verify jBCrypt library is available (org.mindrot:jbcrypt:0.4)\n4. Review application logs for detailed password verification debug output\n5. Use test-password-verification.scala to validate hash generation\n6. Ensure database view returns expected user data\n\n### Callback URL Issues\n\nIf authentication succeeds but redirects to wrong URL:\n\n1. Check the `consumer` table `redirecturl` field:\n\n   ```sql\n   SELECT consumerid, redirecturl FROM consumer WHERE consumerid = 'obp-api-client';\n   ```\n\n2. Should be: `http://localhost:8080/auth/openid-connect/callback` (not `/oauth/callback`)\n\n3. Fix with: `psql -d sandbox -f fix-callback-url.sql`\n\n4. Restart OBP-OIDC service after database changes\n\n## TRACE Logging\n\n### Enabling Detailed Debug Logs\n\nFor troubleshooting authentication flows, token generation, and other detailed operations, you can enable TRACE level logging:\n\n**Normal logging (DEBUG level):**\n\n```bash\n./run-server.sh\n```\n\n**TRACE logging enabled:**\n\n```bash\nOIDC_ENABLE_TRACE_LOGGING=true ./run-server.sh\n```\n\n### What TRACE Logs Show\n\nWhen TRACE logging is enabled, you'll see detailed information about:\n\n- **Authorization code validation**: Entry points, code lookup, validation results\n- **Token generation**: ID token creation, access token creation, JWT signing\n- **User authentication**: Database queries, password verification steps\n- **Client operations**: Client lookup, validation processes\n- **Internal state**: Memory storage contents, processing steps\n\n**Example TRACE output:**\n\n```\nvalidateAndConsumeCode ENTRY - code: 12345678..., clientId: abc123\nFound 5 stored codes in memory\nAuthorization code validation SUCCESS for sub: user123\nGenerating ID token for user: user123, client: abc123\nSetting azp (Authorized Party) claim to: abc123\nID token generated successfully with azp: abc123\n```\n\n### Use Cases for TRACE Logging\n\n- **Debugging authentication failures**: See exactly where the process fails\n- **Token generation issues**: Track JWT creation and claims\n- **Integration problems**: Understand the complete OIDC flow\n- **Performance analysis**: Identify bottlenecks in the authentication process\n- **Development**: Understand internal workings during feature development\n\n**Note:** TRACE logging is temporary per session and doesn't modify configuration files. It uses system properties to override the default DEBUG level logging.\n\n## License\n\nThis project is licensed under the same terms as the Open Bank Project.\n\n## Features\n\n- **Pure Functional Programming**: Built with Cats Effect IO and immutable data structures\n- **Modern Scala**: Uses http4s, Circe for JSON, and functional error handling\n- **PostgreSQL Database**: Authenticates real users from OBP authuser table via read-only view\n- **Complete OIDC Support**: All essential endpoints for authorization code flow\n- **Client Management**: CRUD operations for OIDC clients via admin database user\n- **Automatic Client Creation**: Auto-creates OBP-API, Portal, Explorer II, and Opey II clients on startup\n- **JWT Tokens**: RS256 signed ID tokens and access tokens\n- **BCrypt Password Verification**: Compatible with OBP-API password hashing\n- **Integration Tests**: Comprehensive test suite demonstrating full OIDC flow\n\n## Technology Stack\n\n- **Language**: Scala 2.13 with functional programming principles\n- **HTTP Framework**: http4s with Ember server\n- **Effect System**: Cats Effect IO\n- **Database**: PostgreSQL with Doobie for functional database access\n- **JSON**: Circe for serialization/deserialization\n- **JWT**: Auth0 Java JWT library\n- **Build Tool**: Maven\n- **Testing**: ScalaTest\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenbankproject%2Fobp-oidc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenbankproject%2Fobp-oidc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenbankproject%2Fobp-oidc/lists"}