LDAP to OAuth2 Bridge
A lightweight LDAP server that authenticates users against an OAuth2/OIDC provider (such as Keycloak). This bridge allows legacy applications that only support LDAP authentication to work with modern OAuth2 identity providers.
Overview
This bridge presents an LDAP interface to applications while performing OAuth2 Resource Owner Password Credentials (ROPC) flow authentication against your identity provider in the background.
Use Case: Integrate applications like TheLounge IRC client, which only support LDAP authentication, with Keycloak or other OAuth2/OIDC providers.
Features
- Lightweight Node.js implementation
- Simple LDAP bind operation support
- OAuth2 Resource Owner Password Credentials flow
- Configurable base DN
- Easy integration with Keycloak and other OIDC providers
- FreeBSD service support (includes rc.d script)
Requirements
- Node.js 14+ and npm
- An OAuth2/OIDC provider (Keycloak, Auth0, etc.)
- A client configured with Direct Access Grants enabled
Installation
1. Clone the repository
git clone https://your-gitea-instance.com/ldap-to-oauth2.git
cd ldap-to-oauth2
2. Install dependencies
npm install
3. Configure OAuth2 Provider
For Keycloak:
- Create a new client in your realm
- Set Access Type to
confidential - Enable Direct Access Grants Enabled
- Save and retrieve the client secret from the Credentials tab
For other providers:
Ensure your OAuth2 provider supports the Resource Owner Password Credentials grant type.
4. Configure the bridge
Edit server.js and update the configuration section:
const LDAP_PORT = 3893;
const KEYCLOAK_URL = 'https://your-keycloak-domain.com';
const KEYCLOAK_REALM = 'your-realm';
const KEYCLOAK_CLIENT_ID = 'your-client-id';
const KEYCLOAK_CLIENT_SECRET = 'your-client-secret';
const BASE_DN = 'dc=example,dc=com';
5. Run the server
node server.js
Testing
Test authentication using ldapsearch:
ldapsearch -H ldap://localhost:3893 \
-D "cn=username,dc=example,dc=com" \
-W \
-b "dc=example,dc=com"
Replace username with a valid username from your OAuth2 provider.
FreeBSD Service Installation
1. Copy files to system directories
# Copy application files
cp -r ldap-to-oauth2 /usr/local/ldap-oauth-bridge
# Copy RC script
cp ldap_oauth_bridge.rc /usr/local/etc/rc.d/ldap_oauth_bridge
chmod +x /usr/local/etc/rc.d/ldap_oauth_bridge
2. Enable and start service
echo 'ldap_oauth_bridge_enable="YES"' >> /etc/rc.conf
service ldap_oauth_bridge start
3. Check service status
service ldap_oauth_bridge status
sockstat -l | grep 3893
Configuration Examples
TheLounge IRC Client
In config.js:
ldap: {
enable: true,
url: "ldap://your-server:3893",
baseDN: "dc=example,dc=com",
searchDN: {
rootDN: "cn=admin,dc=example,dc=com",
rootPassword: "dummy",
filter: "(|(uid=%s)(cn=%s))"
}
}
Generic LDAP Application
- LDAP Server:
ldap://your-server:3893 - Base DN:
dc=example,dc=com - Bind DN Format:
cn=USERNAME,dc=example,dc=com
Users authenticate with their OAuth2 provider username and password.
How It Works
- Application sends LDAP BIND request with username and password
- Bridge extracts username from the LDAP DN (e.g.,
cn=alice,dc=example,dc=com→alice) - Bridge performs OAuth2 password grant flow with the identity provider
- If OAuth2 authentication succeeds, LDAP BIND succeeds
- If OAuth2 authentication fails, LDAP BIND fails
Security Considerations
- Transport Security: Use LDAPS (LDAP over TLS) in production or ensure the bridge runs on a trusted network
- Port < 1024: Requires root privileges on Unix systems. Consider using port 3893 or higher to avoid running as root
- Password Grant Flow: The Resource Owner Password Credentials flow passes passwords to the bridge. Ensure secure communication channels
- Network Isolation: Run the bridge on the same network as your applications or use VPN/tunneling
Limitations
- Only supports LDAP BIND operations (authentication only)
- Does not provide a full LDAP directory (no user enumeration, group queries, etc.)
- Search operations return empty results
- Requires OAuth2 provider to support Resource Owner Password Credentials grant
Troubleshooting
Authentication fails
- Check server logs for detailed error messages
- Verify OAuth2 client credentials are correct
- Ensure Direct Access Grants are enabled in your OAuth2 client
- Test OAuth2 authentication directly using curl:
curl -X POST https://your-keycloak/realms/your-realm/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=your-client-id" \
-d "client_secret=your-client-secret" \
-d "username=testuser" \
-d "password=testpass"
Connection refused
- Verify the server is running:
sockstat -l | grep 3893 - Check firewall rules
- Ensure the application can reach the bridge server
DN parsing errors
- Ensure username is formatted as
cn=username,dc=example,dc=comoruid=username,dc=example,dc=com - Check server logs for DN parsing details
License
MIT License - See LICENSE file for details
Contributing
Contributions are welcome! Please submit pull requests or open issues on the repository.
Author
Created for use with TheLounge IRC client and Keycloak authentication.