Skip to main content
Glama
orneryd

M.I.M.I.R - Multi-agent Intelligent Memory & Insight Repository

by orneryd
LOCAL_OAUTH_TESTING.md10.7 kB
# Local OAuth Provider Testing This guide explains how to test the full OAuth 2.0 Authorization Code flow using a local OAuth provider. ## 🎯 Quick Reference | Task | Command | |------|---------| | Start OAuth provider | `npx tsx testing/local-oauth-provider.ts` | | Run automated tests | `npm run test:oauth` | | Check provider health | `curl http://localhost:8888/health` | | View discovery metadata | `curl http://localhost:8888/.well-known/oauth-authorization-server` | | Test login flow | Navigate to `http://localhost:9042` and click "Login" | **Default Test Users:** - `admin` / `admin123` - Full admin access - `developer` / `dev123` - Developer access - `viewer` / `view123` - Read-only access **Ports:** - OAuth Provider: `8888` - Mimir Server: `9042` ## Why Use This? - **No external dependencies**: Test OAuth without registering apps with Google, GitHub, etc. - **Localhost redirects**: External providers often don't allow `localhost` redirects - **Multiple test users**: Pre-configured users with different roles for RBAC testing - **Full flow testing**: Tests authorization, token exchange, and userinfo endpoints ## Quick Start ### 1. Start the Local OAuth Provider ```bash npx tsx testing/local-oauth-provider.ts ``` You should see: ``` 🚀 Local OAuth Provider running on http://localhost:8888 📋 Configuration for .env file: MIMIR_AUTH_PROVIDER=oauth MIMIR_OAUTH_ISSUER=http://localhost:8888 MIMIR_OAUTH_CLIENT_ID=mimir-local-test MIMIR_OAUTH_CLIENT_SECRET=local-test-secret-123 MIMIR_OAUTH_CALLBACK_URL=http://localhost:9042/auth/oauth/callback 👥 Test Users: • admin / admin123 - [admin, developer] • developer / dev123 - [developer] • viewer / view123 - [viewer] ✅ Ready to accept OAuth requests! ``` ### 2. Configure Mimir Add to your `.env` file: ```bash # Enable security MIMIR_ENABLE_SECURITY=true MIMIR_AUTH_PROVIDER=oauth MIMIR_ENV=development # JWT Secret (required for stateless auth) MIMIR_JWT_SECRET=test-secret-12345 # Local OAuth Provider Configuration # IMPORTANT: Use explicit endpoint URLs - different providers have different paths! # - Use host.docker.internal for token/userinfo endpoints (server-side requests from container) # - Use localhost for authorization endpoint (browser redirects from client) MIMIR_OAUTH_CLIENT_ID=mimir-local-test MIMIR_OAUTH_CLIENT_SECRET=local-test-secret-123 MIMIR_OAUTH_CALLBACK_URL=http://localhost:9042/auth/oauth/callback MIMIR_OAUTH_AUTHORIZATION_URL=http://localhost:8888/oauth2/v1/authorize MIMIR_OAUTH_TOKEN_URL=http://host.docker.internal:8888/oauth2/v1/token MIMIR_OAUTH_USERINFO_URL=http://host.docker.internal:8888/oauth2/v1/userinfo MIMIR_OAUTH_ALLOW_HTTP=true # Required for local HTTP OAuth testing # Optional: Customize provider display name # MIMIR_OAUTH_PROVIDER_NAME=Local Test OAuth ``` **Important Notes:** - **Authorization URL** uses `localhost` because the browser makes this request - **Token/Userinfo URLs** use `host.docker.internal` if running Mimir in Docker (server-side requests) - If running Mimir natively (not in Docker), use `localhost` for all URLs - `MIMIR_OAUTH_ALLOW_HTTP=true` is required to bypass HTTPS enforcement for local testing ### 3. Start Mimir ```bash npm run dev # or docker compose up ``` ### 4. Test the OAuth Flow 1. Navigate to `http://localhost:9042` 2. Click "Login with Local Test OAuth" 3. You'll be redirected to `http://localhost:8888/oauth2/v1/authorize` 4. Select a test user from the dropdown 5. Click "Authorize & Continue" 6. You'll be redirected back to Mimir with an authenticated session ## Test Users | Username | Password | Roles | Use Case | |-----------|----------|--------------------|-----------------------------| | admin | admin123 | admin, developer | Full admin access testing | | developer | dev123 | developer | Developer role testing | | viewer | view123 | viewer | Read-only access testing | ## OAuth Flow Details ### 1. Authorization Request ``` GET http://localhost:8888/oauth2/v1/authorize? response_type=code& client_id=mimir-local-test& redirect_uri=http://localhost:9042/auth/oauth/callback& scope=openid%20profile%20email& state=random_state_string ``` ### 2. User Consent - User selects test user and clicks "Authorize" - Provider generates authorization code - Redirects to callback with code ### 3. Token Exchange ``` POST http://localhost:8888/oauth2/v1/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code& code=AUTHORIZATION_CODE& redirect_uri=http://localhost:9042/auth/oauth/callback& client_id=mimir-local-test& client_secret=local-test-secret-123 ``` Response: ```json { "access_token": "...", "token_type": "Bearer", "expires_in": 3600, "scope": "openid profile email" } ``` ### 4. Userinfo Request ``` GET http://localhost:8888/oauth2/v1/userinfo Authorization: Bearer ACCESS_TOKEN ``` Response: ```json { "sub": "user-001", "email": "admin@localhost", "preferred_username": "admin", "roles": ["admin", "developer"] } ``` ## Troubleshooting ### "Invalid client_id" - Make sure `MIMIR_OAUTH_CLIENT_ID=mimir-local-test` in your `.env` ### "redirect_uri mismatch" - Verify `MIMIR_OAUTH_CALLBACK_URL=http://localhost:9042/auth/oauth/callback` - Check ports (OAuth provider: 8888, Mimir: 9042) ### "Authorization code expired" - Authorization codes expire after 10 minutes - Restart the OAuth flow ### Network Errors - Ensure both OAuth provider (8888) and Mimir (9042) are running - Check firewall/network settings ## Endpoints | Endpoint | Method | Description | |----------|--------|-------------| | `/oauth2/v1/authorize` | GET | Authorization endpoint (shows consent form) | | `/oauth2/v1/authorize/consent` | POST | Processes user consent | | `/oauth2/v1/token` | POST | Token exchange | | `/oauth2/v1/userinfo` | GET | User profile | | `/.well-known/oauth-authorization-server` | GET | Discovery endpoint | | `/health` | GET | Health check | ## Customization ### Add More Test Users Edit `testing/local-oauth-provider.ts`: ```typescript const users = [ { sub: 'user-004', email: 'custom@localhost', preferred_username: 'custom', roles: ['custom-role'], password: 'custom123' } ]; ``` ### Change Port ```typescript const PORT = 8888; // Change this const ISSUER = 'http://localhost:8888'; // Update this too ``` ### Modify Client Credentials ```typescript const CLIENT_ID = 'your-client-id'; const CLIENT_SECRET = 'your-client-secret'; ``` ## Validating OAuth Flows ### Manual Flow Validation **Step 1: Test Authorization Endpoint** ```bash # Open in browser or use curl curl "http://localhost:8888/oauth2/v1/authorize?response_type=code&client_id=mimir-local-test&redirect_uri=http://localhost:9042/auth/oauth/callback&state=test123" ``` Expected: HTML login form with test users **Step 2: Test Discovery Endpoint** ```bash curl http://localhost:8888/.well-known/oauth-authorization-server | jq ``` Expected: ```json { "issuer": "http://localhost:8888", "authorization_endpoint": "http://localhost:8888/oauth2/v1/authorize", "token_endpoint": "http://localhost:8888/oauth2/v1/token", "userinfo_endpoint": "http://localhost:8888/oauth2/v1/userinfo", "response_types_supported": ["code"], "grant_types_supported": ["authorization_code"] } ``` **Step 3: Test Token Exchange (requires auth code from Step 1)** ```bash # After completing Step 1, you'll get an auth code in the redirect curl -X POST http://localhost:8888/oauth2/v1/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code" \ -d "code=YOUR_AUTH_CODE_HERE" \ -d "redirect_uri=http://localhost:9042/auth/oauth/callback" \ -d "client_id=mimir-local-test" \ -d "client_secret=local-test-secret-123" ``` Expected: ```json { "access_token": "...", "token_type": "Bearer", "expires_in": 3600, "scope": "openid profile email" } ``` **Step 4: Test Userinfo Endpoint** ```bash # Use access_token from Step 3 curl http://localhost:8888/oauth2/v1/userinfo \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE" ``` Expected: ```json { "sub": "user-001", "email": "admin@localhost", "preferred_username": "admin", "roles": ["admin", "developer"] } ``` ### Automated Testing Run the OAuth flow test script: ```bash npm run test:oauth ``` This script validates: - ✅ Authorization endpoint accessibility - ✅ Token exchange with valid credentials - ✅ Userinfo retrieval with access token - ✅ Error handling for invalid credentials - ✅ Token expiration behavior ### Debugging OAuth Issues **Enable verbose logging:** In `testing/local-oauth-provider.ts`, all requests are logged with `[OAuth Provider]` prefix. Watch the console output: ```bash npx tsx testing/local-oauth-provider.ts ``` **Common validation failures:** 1. **State mismatch**: Check that `state` parameter is preserved through redirect 2. **Code reuse**: Authorization codes are single-use only 3. **Redirect URI mismatch**: Must match exactly (including trailing slashes) 4. **Token expiration**: Auth codes expire in 10 minutes, access tokens in 1 hour 5. **Client credentials**: Verify `CLIENT_ID` and `CLIENT_SECRET` match **Network debugging:** ```bash # Check OAuth provider is running curl http://localhost:8888/health # Check Mimir is running curl http://localhost:9042/health # Test full redirect flow curl -v "http://localhost:8888/oauth2/v1/authorize?response_type=code&client_id=mimir-local-test&redirect_uri=http://localhost:9042/auth/oauth/callback&state=test" ``` ### Testing Different Scenarios **Test invalid client:** ```bash curl "http://localhost:8888/oauth2/v1/authorize?response_type=code&client_id=invalid-client&redirect_uri=http://localhost:9042/auth/oauth/callback" ``` Expected: 400 error "Invalid client_id" **Test expired code:** 1. Get an auth code 2. Wait 11 minutes 3. Try to exchange it Expected: 400 error "Authorization code expired" **Test invalid token:** ```bash curl http://localhost:8888/oauth2/v1/userinfo \ -H "Authorization: Bearer invalid-token" ``` Expected: 401 error "Invalid access token" **Test role-based access:** 1. Login as `viewer` (roles: ["viewer"]) 2. Verify user profile in response 3. Test that Mimir enforces role restrictions ## Production Notes ⚠️ **This is for TESTING ONLY!** - No password hashing - No persistent storage - No rate limiting - No HTTPS support - Minimal security checks - Hardcoded credentials - No PKCE support - No refresh tokens For production, use a real OAuth provider like: - Okta - Auth0 - Azure AD - Google OAuth - GitHub OAuth - Keycloak

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/orneryd/Mimir'

If you have feedback or need assistance with the MCP directory API, please join our Discord server