# OpenLDAP + Keycloak OIDC Lab Setup A Docker-based lab for testing SSO with OIDC on Apple Silicon (M1/M2/M3). ## Quick Start ```bash docker compose up -d ``` ## Access Points | Service | URL | Credentials | |---------|-----|-------------| | **Keycloak** | http://localhost:8080 | admin / admin | | **LDAP Admin** | http://localhost:8081 | See below | | **OpenLDAP** | ldap://localhost:389 | See below | --- ## Step 1: Login to LDAP Admin 1. Open http://localhost:8081 2. Click **"login"** on the left sidebar 3. Enter: | Field | Value | |-------|-------| | Login DN | `cn=admin,dc=lab,dc=local` | | Password | `admin123` | --- ## Step 2: Create Test Users in LDAP ### Option A: Via Command Line **1. Create organizational unit for users:** ```bash printf 'dn: ou=users,dc=lab,dc=local\nobjectClass: organizationalUnit\nou: users\n' | docker exec -i openldap ldapadd -x -H ldap://localhost -D "cn=admin,dc=lab,dc=local" -w admin123 ``` **2. Create test user:** ```bash printf 'dn: cn=testuser,ou=users,dc=lab,dc=local\nobjectClass: inetOrgPerson\ncn: testuser\nsn: User\ngivenName: Test\nuid: testuser\nuserPassword: Password123\nmail: testuser@lab.local\n' | docker exec -i openldap ldapadd -x -H ldap://localhost -D "cn=admin,dc=lab,dc=local" -w admin123 ``` **3. Create another user:** ```bash printf 'dn: cn=jdoe,ou=users,dc=lab,dc=local\nobjectClass: inetOrgPerson\ncn: jdoe\nsn: Doe\ngivenName: John\nuid: jdoe\nuserPassword: Password123\nmail: jdoe@lab.local\n' | docker exec -i openldap ldapadd -x -H ldap://localhost -D "cn=admin,dc=lab,dc=local" -w admin123 ``` ### Option B: Via LDAP Admin UI 1. Login to http://localhost:8081 2. Expand `dc=lab,dc=local` in the tree 3. Click "Create new entry here" 4. Select "Generic: Organisational Unit" → name it `users` 5. Inside `ou=users`, create "Generic: User Account" --- ## Step 3: Configure Keycloak ### 3.1 Create a Realm 1. Open http://localhost:8080 2. Login with `admin` / `admin` 3. Click dropdown (top-left, says "master") → **Create realm** 4. Name: `lab` 5. Click **Create** ### 3.2 Add LDAP User Federation 1. Go to **User federation** (left menu, bottom) 2. Click **Add Ldap providers** 3. Fill in: | Setting | Value | |---------|-------| | UI display name | `OpenLDAP` | | Vendor | `Other` | | Connection URL | `ldap://openldap:389` | | Bind DN | `cn=admin,dc=lab,dc=local` | | Bind credentials | `admin123` | | Edit mode | `WRITABLE` | | Users DN | `ou=users,dc=lab,dc=local` | | Username LDAP attribute | `uid` | | RDN LDAP attribute | `cn` | | UUID LDAP attribute | `entryUUID` | | User object classes | `inetOrgPerson` | 4. Click **Save** 5. Click **Action**(top right) dropdown → **Sync all users** ### 3.3 Verify Users Synced 1. Go to **Users** (left menu) 2. Click **View all users** 3. You should see `testuser` and `jdoe` --- ## Step 4: Create an OIDC Client 1. Go to **Clients** → **Create client** 2. Fill in: - Client type: `OpenID Connect` - Client ID: `my-test-app` - Click **Next** 3. Client authentication: `On` 4. Click **Next** 5. Valid redirect URIs: `http://localhost:3000/*` - Also add: `https://oidcdebugger.com/debug` 6. Click **Save** 7. Go to **Credentials** tab → Copy the **Client secret** --- ## Step 5: Test OIDC ### OIDC Discovery Endpoint ``` http://localhost:8080/realms/lab/.well-known/openid-configuration ``` ### Test with OIDC Debugger (easiest) 1. Go to https://oidcdebugger.com 2. Fill in: | Field | Value | |-------|-------| | Authorize URI | `http://localhost:8080/realms/lab/protocol/openid-connect/auth` | | Redirect URI | `https://oidcdebugger.com/debug` | | Client ID | `my-test-app` | | Scope | `openid profile email` | | Response type | `code` | 3. Click **Send Request** 4. Login with `testuser` / `Password123` 5. You'll get an authorization code back ### Test with curl ```bash # Get token using password grant (for testing only) curl -X POST http://localhost:8080/realms/lab/protocol/openid-connect/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "client_id=my-test-app" \ -d "client_secret=YOUR_CLIENT_SECRET" \ -d "grant_type=password" \ -d "username=testuser" \ -d "password=Password123" | jq ``` ### Decode the Token Copy the `access_token` or `id_token` and paste at https://jwt.io to see the claims. --- ## Architecture ``` ┌─────────────────────────────────────────────┐ │ Your App / OIDC Debugger │ └──────────────────┬──────────────────────────┘ │ OIDC (authorize, token) ▼ ┌─────────────────────────────────────────────┐ │ Keycloak :8080 │ │ (Identity Provider) │ └──────────────────┬──────────────────────────┘ │ LDAP bind (auth check) ▼ ┌─────────────────────────────────────────────┐ │ OpenLDAP :389 │ │ (User Directory) │ └─────────────────────────────────────────────┘ ``` --- ## Useful Commands ```bash # View logs docker compose logs -f # List LDAP users docker exec openldap ldapsearch -x -H ldap://localhost -b "dc=lab,dc=local" -D "cn=admin,dc=lab,dc=local" -w "admin123" # Reset user password docker exec openldap ldappasswd -x -D "cn=admin,dc=lab,dc=local" -w "admin123" -s "NewPass123!" "cn=testuser,ou=users,dc=lab,dc=local" # Delete a user docker exec openldap ldapdelete -x -D "cn=admin,dc=lab,dc=local" -w "admin123" "cn=testuser,ou=users,dc=lab,dc=local" # Stop everything docker compose down # Stop and delete all data docker compose down -v ``` --- ## Troubleshooting **Keycloak can't connect to LDAP:** - Verify OpenLDAP is running: `docker compose ps` - Test connection: `docker exec keycloak curl -v ldap://openldap:389` **Users not syncing:** - Make sure `ou=users` exists in LDAP - Check Users DN is: `ou=users,dc=lab,dc=local` - Try "Sync all users" again in Keycloak **LDAP Admin won't login:** - Use full DN: `cn=admin,dc=lab,dc=local` - Password: `admin123` **Port 389 already in use:** - Change port in docker-compose.yml: `"3389:389"` - Update Keycloak connection URL accordingly --- ## Next Steps - [ ] Test SAML SSO (Keycloak supports both OIDC and SAML) - [ ] Add MFA/2FA in Keycloak - [ ] Try social login (Google, GitHub) alongside LDAP users - [ ] Build a sample app that uses OIDC login - [ ] Explore Keycloak themes and branding