🎯 Recommended Samples
Balanced sample collections from various categories for you to explore
LDAP Samples
LDAP (Lightweight Directory Access Protocol) implementation examples for user authentication, directory operations, and Active Directory integration
💻 LDAP User Authentication python
🟡 intermediate
⭐⭐⭐⭐
Complete LDAP authentication system with user login, password verification, and session management
⏱️ 40 min
🏷️ ldap, authentication, security, directory
Prerequisites:
LDAP concepts, Python programming, Directory services
#!/usr/bin/env python3
"""
LDAP User Authentication System
Complete implementation for authenticating users against LDAP/Active Directory
"""
import ldap
import ldap.modlist
import hashlib
import secrets
import time
from typing import Dict, Optional, List, Any
from dataclasses import dataclass
from datetime import datetime, timedelta
import ssl
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@dataclass
class LDAPConfig:
"""LDAP configuration"""
server: str # LDAP server hostname/IP
port: int = 389 # Default LDAP port
use_ssl: bool = False # Use LDAPS
use_tls: bool = True # Start TLS
bind_dn: str # Bind DN for authentication
bind_password: str # Bind password
base_dn: str # Base DN for searches
user_search_filter: str = '(uid={username})' # User search filter
user_attributes: List[str] = None # Attributes to retrieve
group_search_filter: str = '(member={user_dn})' # Group search filter
def __post_init__(self):
if self.user_attributes is None:
self.user_attributes = ['uid', 'cn', 'mail', 'memberOf', 'sn', 'givenName']
class LDAPAuthenticator:
"""LDAP Authentication Handler"""
def __init__(self, config: LDAPConfig):
self.config = config
self.connection = None
self._initialize_connection()
def _initialize_connection(self):
"""Initialize LDAP connection"""
try:
# Create connection
if self.config.use_ssl:
# LDAPS connection
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)
self.connection = ldap.initialize(f"ldaps://{self.config.server}:{self.config.port}")
else:
# Standard LDAP connection
self.connection = ldap.initialize(f"ldap://{self.config.server}:{self.config.port}")
# Configure TLS if needed
if self.config.use_tls:
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)
self.connection.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
# Set connection options
self.connection.set_option(ldap.OPT_REFERRALS, 0)
self.connection.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
self.connection.set_option(ldap.OPT_NETWORK_TIMEOUT, 10)
logger.info(f"LDAP connection initialized to {self.config.server}:{self.config.port}")
except Exception as e:
logger.error(f"Failed to initialize LDAP connection: {str(e)}")
raise LDAPConnectionError(f"Connection failed: {str(e)}")
def bind(self):
"""Bind to LDAP server with service account"""
try:
self.connection.simple_bind_s(self.config.bind_dn, self.config.bind_password)
logger.info("Successfully bound to LDAP server")
except ldap.INVALID_CREDENTIALS:
raise LDAPAuthenticationError("Invalid bind credentials")
except ldap.LDAPError as e:
raise LDAPConnectionError(f"Bind failed: {str(e)}")
def authenticate_user(self, username: str, password: str) -> Dict[str, Any]:
"""
Authenticate user against LDAP
Args:
username: Username to authenticate
password: User password
Returns:
Dictionary containing user information
Raises:
LDAPAuthenticationError: If authentication fails
"""
try:
# First, bind with service account to search for user
self.bind()
# Search for user
user_dn = self._find_user_dn(username)
if not user_dn:
raise LDAPAuthenticationError("User not found")
# Verify user password by binding as the user
try:
user_connection = ldap.initialize(f"ldap://{self.config.server}:{self.config.port}")
user_connection.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
user_connection.set_option(ldap.OPT_REFERRALS, 0)
if self.config.use_tls:
user_connection.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)
user_connection.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
user_connection.start_tls_s()
user_connection.simple_bind_s(user_dn, password)
user_connection.unbind()
logger.info(f"User {username} authenticated successfully")
except ldap.INVALID_CREDENTIALS:
raise LDAPAuthenticationError("Invalid password")
except Exception as e:
raise LDAPAuthenticationError(f"User bind failed: {str(e)}")
# Get user attributes
user_info = self._get_user_attributes(user_dn, username)
# Get user groups
user_groups = self._get_user_groups(user_dn)
# Create session token
session_token = self._create_session_token(username, user_dn)
return {
'username': username,
'dn': user_dn,
'attributes': user_info,
'groups': user_groups,
'session_token': session_token,
'authenticated_at': datetime.utcnow().isoformat()
}
finally:
if self.connection:
try:
self.connection.unbind()
except:
pass
def _find_user_dn(self, username: str) -> Optional[str]:
"""Find user Distinguished Name"""
try:
search_filter = self.config.user_search_filter.format(username=username)
result = self.connection.search_s(
self.config.base_dn,
ldap.SCOPE_SUBTREE,
search_filter,
['dn']
)
if result and len(result) > 0:
return result[0][0] # Return the DN
return None
except Exception as e:
logger.error(f"Error finding user DN: {str(e)}")
return None
def _get_user_attributes(self, user_dn: str, username: str) -> Dict[str, Any]:
"""Get user attributes from LDAP"""
try:
search_filter = self.config.user_search_filter.format(username=username)
result = self.connection.search_s(
self.config.base_dn,
ldap.SCOPE_SUBTREE,
search_filter,
self.config.user_attributes
)
if result and len(result) > 0:
attributes = result[0][1] # Get attributes dictionary
# Convert byte strings to regular strings
user_attrs = {}
for key, values in attributes.items():
if isinstance(values, list):
user_attrs[key] = [v.decode('utf-8') if isinstance(v, bytes) else v for v in values]
elif isinstance(values, bytes):
user_attrs[key] = values.decode('utf-8')
else:
user_attrs[key] = values
return user_attrs
return {}
except Exception as e:
logger.error(f"Error getting user attributes: {str(e)}")
return {}
def _get_user_groups(self, user_dn: str) -> List[str]:
"""Get user group memberships"""
try:
search_filter = self.config.group_search_filter.format(user_dn=user_dn)
result = self.connection.search_s(
self.config.base_dn,
ldap.SCOPE_SUBTREE,
search_filter,
['cn', 'dn']
)
groups = []
for group_dn, group_attrs in result:
if 'cn' in group_attrs:
cn_values = group_attrs['cn']
if isinstance(cn_values, list):
groups.extend([cn.decode('utf-8') if isinstance(cn, bytes) else cn for cn in cn_values])
else:
groups.append(cn_values.decode('utf-8') if isinstance(cn_values, bytes) else cn_values)
return groups
except Exception as e:
logger.error(f"Error getting user groups: {str(e)}")
return []
def _create_session_token(self, username: str, user_dn: str) -> str:
"""Create session token for authenticated user"""
token_data = {
'username': username,
'user_dn': user_dn,
'timestamp': int(time.time()),
'expires': int(time.time()) + 3600, # 1 hour
'nonce': secrets.token_hex(16)
}
# Create hash-based token (in production, use JWT)
token_string = f"{token_data['username']}:{token_data['timestamp']}:{token_data['expires']}:{token_data['nonce']}"
token_hash = hashlib.sha256(token_string.encode()).hexdigest()
return f"{token_string}:{token_hash}"
def validate_session_token(self, token: str) -> Dict[str, Any]:
"""Validate session token"""
try:
parts = token.split(':')
if len(parts) != 5:
return {'valid': False, 'error': 'Invalid token format'}
username, timestamp_str, expires_str, nonce, token_hash = parts
# Verify hash
token_string = f"{username}:{timestamp_str}:{expires_str}:{nonce}"
calculated_hash = hashlib.sha256(token_string.encode()).hexdigest()
if calculated_hash != token_hash:
return {'valid': False, 'error': 'Invalid token hash'}
# Check expiration
expires = int(expires_str)
if time.time() > expires:
return {'valid': False, 'error': 'Token expired'}
return {
'valid': True,
'username': username,
'timestamp': int(timestamp_str),
'expires': expires
}
except Exception as e:
return {'valid': False, 'error': str(e)}
def search_users(self, query: str, limit: int = 50) -> List[Dict[str, Any]]:
"""Search for users in LDAP"""
try:
self.bind()
search_filter = f"(|(uid=*{query}*)(cn=*{query}*)(mail=*{query}*))"
result = self.connection.search_s(
self.config.base_dn,
ldap.SCOPE_SUBTREE,
search_filter,
self.config.user_attributes,
attrlist=self.config.user_attributes,
sizelimit=limit
)
users = []
for user_dn, user_attrs in result:
user_info = {'dn': user_dn}
# Convert attributes
for key, values in user_attrs.items():
if isinstance(values, list):
user_info[key] = [v.decode('utf-8') if isinstance(v, bytes) else v for v in values]
elif isinstance(values, bytes):
user_info[key] = values.decode('utf-8')
else:
user_info[key] = values
users.append(user_info)
return users
except Exception as e:
logger.error(f"Error searching users: {str(e)}")
return []
finally:
if self.connection:
try:
self.connection.unbind()
except:
pass
def create_user(self, user_data: Dict[str, Any], password: str) -> bool:
"""Create a new user in LDAP"""
try:
self.bind()
# Build user DN
username = user_data.get('uid')
if not username:
raise ValueError("Username (uid) is required")
user_dn = f"uid={username},{self.config.base_dn}"
# Build user attributes
attributes = {}
for key, value in user_data.items():
if key != 'uid': # uid is already in DN
if isinstance(value, list):
attributes[key] = [v.encode('utf-8') if isinstance(v, str) else v for v in value]
else:
attributes[key] = value.encode('utf-8') if isinstance(value, str) else value
# Required object classes
attributes['objectClass'] = [
'top',
'person',
'organizationalPerson',
'inetOrgPerson'
]
# Add user password
import passlib.hash
hashed_password = passlib.hash.ldap_salted_sha1.hash(password)
attributes['userPassword'] = hashed_password.encode('utf-8')
# Add the user
ldif = ldap.modlist.addModlist(attributes)
self.connection.add_s(user_dn, ldif)
logger.info(f"User {username} created successfully")
return True
except Exception as e:
logger.error(f"Error creating user: {str(e)}")
return False
finally:
if self.connection:
try:
self.connection.unbind()
except:
pass
class LDAPConnectionError(Exception):
"""LDAP connection error"""
pass
class LDAPAuthenticationError(Exception):
"""LDAP authentication error"""
pass
# Example usage
if __name__ == "__main__":
# Configuration
ldap_config = LDAPConfig(
server="ldap.example.com",
port=389,
use_ssl=False,
use_tls=True,
bind_dn="cn=admin,dc=example,dc=com",
bind_password="admin_password",
base_dn="dc=example,dc=com",
user_search_filter="(uid={username})",
user_attributes=["uid", "cn", "mail", "memberOf", "sn", "givenName", "telephoneNumber"],
group_search_filter="(member={user_dn})"
)
# Create authenticator
authenticator = LDAPAuthenticator(ldap_config)
try:
# Authenticate user
user_info = authenticator.authenticate_user("johndoe", "user_password")
print(f"User authenticated: {user_info['username']}")
print(f"Email: {user_info['attributes'].get('mail', ['N/A'])[0]}")
print(f"Groups: {user_info['groups']}")
print(f"Session token: {user_info['session_token']}")
# Validate session token
token_validation = authenticator.validate_session_token(user_info['session_token'])
print(f"Token valid: {token_validation['valid']}")
# Search users
users = authenticator.search_users("john", limit=5)
print(f"Found {len(users)} users")
except LDAPAuthenticationError as e:
print(f"Authentication failed: {str(e)}")
except LDAPConnectionError as e:
print(f"Connection failed: {str(e)}")
except Exception as e:
print(f"Error: {str(e)}")
# Flask integration example
"""
from flask import Flask, request, jsonify, session
import functools
app = Flask(__name__)
app.secret_key = 'your-secret-key'
# Initialize LDAP authenticator
ldap_auth = LDAPAuthenticator(ldap_config)
def require_auth(f):
@functools.wraps(f)
def decorated(*args, **kwargs):
token = request.headers.get('Authorization')
if not token:
return jsonify({'error': 'Missing authorization token'}), 401
# Remove 'Bearer ' prefix if present
if token.startswith('Bearer '):
token = token[7:]
validation = ldap_auth.validate_session_token(token)
if not validation['valid']:
return jsonify({'error': 'Invalid or expired token'}), 401
return f(*args, **kwargs)
return decorated
@app.route('/login', methods=['POST'])
def login():
data = request.get_json()
username = data.get('username')
password = data.get('password')
if not username or not password:
return jsonify({'error': 'Username and password required'}), 400
try:
user_info = ldap_auth.authenticate_user(username, password)
return jsonify({
'message': 'Login successful',
'user': {
'username': user_info['username'],
'email': user_info['attributes'].get('mail', [''])[0],
'groups': user_info['groups']
},
'token': user_info['session_token']
})
except LDAPAuthenticationError as e:
return jsonify({'error': str(e)}), 401
@app.route('/users/search')
@require_auth
def search_users():
query = request.args.get('q', '')
limit = int(request.args.get('limit', 10))
users = ldap_auth.search_users(query, limit)
return jsonify({'users': users})
@app.route('/profile')
@require_auth
def profile():
token = request.headers.get('Authorization')[7:] # Remove 'Bearer '
validation = ldap_auth.validate_session_token(token)
username = validation['username']
user_info = ldap_auth._get_user_attributes(f"uid={username},{ldap_config.base_dn}", username)
return jsonify({
'username': username,
'attributes': user_info
})
"""
export { LDAPAuthenticator, LDAPConfig, LDAPConnectionError, LDAPAuthenticationError };
💻 Active Directory Integration csharp
🟡 intermediate
⭐⭐⭐⭐
Integration with Microsoft Active Directory for user authentication and group management
⏱️ 50 min
🏷️ active directory, ldap, authentication, windows
Prerequisites:
Active Directory concepts, C# programming, Windows authentication
using System;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace LDAP.ActiveDirectory
{
/// <summary>
/// Active Directory integration service for authentication and user management
/// </summary>
public class ActiveDirectoryService : IDisposable
{
private readonly IConfiguration _configuration;
private readonly ILogger<ActiveDirectoryService> _logger;
private readonly string _domain;
private readonly string _container;
private readonly string _serviceAccountUsername;
private readonly string _serviceAccountPassword;
private readonly string _ldapPath;
// Principal context for Active Directory operations
private PrincipalContext _context;
public ActiveDirectoryService(IConfiguration configuration, ILogger<ActiveDirectoryService> logger)
{
_configuration = configuration;
_logger = logger;
// Load configuration
_domain = configuration["ActiveDirectory:Domain"] ?? "corp.example.com";
_container = configuration["ActiveDirectory:Container"] ?? "DC=corp,DC=example,DC=com";
_serviceAccountUsername = configuration["ActiveDirectory:ServiceAccountUsername"] ?? "svc_ldap";
_serviceAccountPassword = configuration["ActiveDirectory:ServiceAccountPassword"] ?? "";
// Build LDAP path
_ldapPath = $"LDAP://{_domain}/{_container}";
InitializeContext();
}
private void InitializeContext()
{
try
{
// Create principal context with service account
_context = new PrincipalContext(
ContextType.Domain,
_domain,
_container,
ContextOptions.Negotiate | ContextOptions.SecureSocketLayer,
_serviceAccountUsername,
_serviceAccountPassword
);
_logger.LogInformation($"Successfully connected to Active Directory domain: {_domain}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to connect to Active Directory");
throw new ActiveDirectoryException("Failed to connect to Active Directory", ex);
}
}
/// <summary>
/// Authenticate user against Active Directory
/// </summary>
public async Task<AuthenticationResult> AuthenticateUserAsync(string username, string password)
{
try
{
// Validate credentials
bool isValid = _context.ValidateCredentials(username, password, ContextOptions.Negotiate);
if (!isValid)
{
return new AuthenticationResult
{
Success = false,
ErrorMessage = "Invalid username or password"
};
}
// Find user principal
UserPrincipal user = UserPrincipal.FindByIdentity(_context, username);
if (user == null)
{
return new AuthenticationResult
{
Success = false,
ErrorMessage = "User not found"
};
}
// Get user information
var userInfo = await GetUserInfoAsync(user);
// Generate session token
var sessionToken = GenerateSessionToken(username, user.Sid.Value);
_logger.LogInformation($"User {username} authenticated successfully");
return new AuthenticationResult
{
Success = true,
User = userInfo,
SessionToken = sessionToken,
ExpiresAt = DateTime.UtcNow.AddHours(8) // 8-hour session
};
}
catch (Exception ex)
{
_logger.LogError(ex, $"Authentication failed for user: {username}");
return new AuthenticationResult
{
Success = false,
ErrorMessage = "Authentication failed"
};
}
}
/// <summary>
/// Get detailed user information from Active Directory
/// </summary>
public async Task<UserInfo> GetUserInfoAsync(string username)
{
try
{
UserPrincipal user = UserPrincipal.FindByIdentity(_context, username);
if (user == null)
{
throw new UserNotFoundException($"User {username} not found");
}
return await GetUserInfoAsync(user);
}
catch (Exception ex)
{
_logger.LogError(ex, $"Failed to get user info for: {username}");
throw;
}
}
private async Task<UserInfo> GetUserInfoAsync(UserPrincipal user)
{
var userInfo = new UserInfo
{
Username = user.SamAccountName,
DisplayName = user.DisplayName,
EmailAddress = user.EmailAddress,
GivenName = user.GivenName,
Surname = user.Surname,
EmployeeId = user.EmployeeId,
Enabled = user.Enabled ?? true,
LastLogon = user.LastLogon,
PasswordLastSet = user.LastPasswordSet,
AccountExpirationDate = user.AccountExpirationDate,
UserPrincipalName = user.UserPrincipalName
};
// Get directory entry for additional attributes
DirectoryEntry directoryEntry = user.GetUnderlyingObject() as DirectoryEntry;
if (directoryEntry != null)
{
// Extract additional properties
userInfo.Title = GetPropertyValue(directoryEntry, "title");
userInfo.Department = GetPropertyValue(directoryEntry, "department");
userInfo.Company = GetPropertyValue(directoryEntry, "company");
userInfo.Office = GetPropertyValue(directoryEntry, "physicalDeliveryOfficeName");
userInfo.TelephoneNumber = GetPropertyValue(directoryEntry, "telephoneNumber");
userInfo.MobilePhone = GetPropertyValue(directoryEntry, "mobile");
userInfo.Manager = GetPropertyValue(directoryEntry, "manager");
// Get group memberships
userInfo.Groups = await GetUserGroupsAsync(user);
// Get distinguished name
userInfo.DistinguishedName = directoryEntry.Properties["distinguishedName"]?.Value?.ToString();
}
return userInfo;
}
private string GetPropertyValue(DirectoryEntry entry, string propertyName)
{
if (entry.Properties[propertyName]?.Value != null)
{
return entry.Properties[propertyName].Value.ToString();
}
return null;
}
/// <summary>
/// Get user group memberships
/// </summary>
public async Task<List<string>> GetUserGroupsAsync(string username)
{
try
{
UserPrincipal user = UserPrincipal.FindByIdentity(_context, username);
if (user == null)
{
return new List<string>();
}
return await GetUserGroupsAsync(user);
}
catch (Exception ex)
{
_logger.LogError(ex, $"Failed to get groups for user: {username}");
return new List<string>();
}
}
private async Task<List<string>> GetUserGroupsAsync(UserPrincipal user)
{
var groups = new List<string>();
try
{
// Get user's authorization groups
var userGroups = user.GetAuthorizationGroups();
foreach (var group in userGroups)
{
if (group is GroupPrincipal groupPrincipal)
{
groups.Add(groupPrincipal.SamAccountName);
}
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Some groups could not be retrieved due to permission issues");
// Fallback to direct groups only
var principalSearchResult = user.GetGroups();
foreach (var group in principalSearchResult)
{
if (group is GroupPrincipal groupPrincipal)
{
groups.Add(groupPrincipal.SamAccountName);
}
}
}
return groups;
}
/// <summary>
/// Search for users in Active Directory
/// </summary>
public async Task<List<UserInfo>> SearchUsersAsync(string searchTerm, int limit = 50)
{
try
{
var users = new List<UserInfo>();
using (var searcher = new PrincipalSearcher(new UserPrincipal(_context)))
{
// Set search criteria
searcher.QueryFilter = new UserPrincipal(_context)
{
// Search by display name, sam account name, or email
DisplayName = $"*{searchTerm}*",
EmailAddress = $"*{searchTerm}*"
};
searcher.QueryFilter = new UserPrincipal(_context)
{
DisplayName = $"*{searchTerm}*"
};
// Custom search filter for multiple attributes
using (var directorySearcher = new DirectorySearcher(new DirectoryEntry(_ldapPath)))
{
directorySearcher.Filter = $"(&(objectCategory=person)(objectClass=user)(|(displayName=*{searchTerm}*)(sAMAccountName=*{searchTerm}*)(mail=*{searchTerm}*)))";
directorySearcher.PropertiesToLoad.AddRange(new[]
{
"sAMAccountName", "displayName", "mail", "givenName", "sn",
"title", "department", "company", "telephoneNumber", "distinguishedName"
});
directorySearcher.SizeLimit = limit;
using (var searchResults = directorySearcher.FindAll())
{
foreach (SearchResult result in searchResults)
{
var userInfo = new UserInfo
{
Username = GetPropertyFromResult(result, "sAMAccountName"),
DisplayName = GetPropertyFromResult(result, "displayName"),
EmailAddress = GetPropertyFromResult(result, "mail"),
GivenName = GetPropertyFromResult(result, "givenName"),
Surname = GetPropertyFromResult(result, "sn"),
Title = GetPropertyFromResult(result, "title"),
Department = GetPropertyFromResult(result, "department"),
Company = GetPropertyFromResult(result, "company"),
TelephoneNumber = GetPropertyFromResult(result, "telephoneNumber"),
DistinguishedName = GetPropertyFromResult(result, "distinguishedName")
};
users.Add(userInfo);
}
}
}
}
return users;
}
catch (Exception ex)
{
_logger.LogError(ex, $"Failed to search users with term: {searchTerm}");
return new List<UserInfo>();
}
}
private string GetPropertyFromResult(SearchResult result, string propertyName)
{
if (result.Properties.Contains(propertyName) && result.Properties[propertyName].Count > 0)
{
return result.Properties[propertyName][0].ToString();
}
return null;
}
/// <summary>
/// Check if user is member of specific group
/// </summary>
public async Task<bool> IsUserInGroupAsync(string username, string groupName)
{
try
{
UserPrincipal user = UserPrincipal.FindByIdentity(_context, username);
if (user == null)
{
return false;
}
GroupPrincipal group = GroupPrincipal.FindByIdentity(_context, groupName);
if (group == null)
{
return false;
}
return user.IsMemberOf(group);
}
catch (Exception ex)
{
_logger.LogError(ex, $"Failed to check group membership for {username} in {groupName}");
return false;
}
}
/// <summary>
/// Generate secure session token
/// </summary>
private string GenerateSessionToken(string username, byte[] userSid)
{
var tokenData = $"{username}:{Convert.ToBase64String(userSid)}:{DateTime.UtcNow:O}";
var tokenBytes = Encoding.UTF8.GetBytes(tokenData);
using (var hmac = new HMACSHA256())
{
var hash = hmac.ComputeHash(tokenBytes);
var token = Convert.ToBase64String(tokenBytes) + "." + Convert.ToBase64String(hash);
return token;
}
}
/// <summary>
/// Validate session token
/// </summary>
public bool ValidateSessionToken(string token, out string username)
{
username = null;
try
{
var parts = token.Split('.');
if (parts.Length != 2)
{
return false;
}
var tokenData = Convert.FromBase64String(parts[0]);
var receivedHash = Convert.FromBase64String(parts[1]);
using (var hmac = new HMACSHA256())
{
var computedHash = hmac.ComputeHash(tokenData);
if (!cryptographicEqual(receivedHash, computedHash))
{
return false;
}
}
var dataString = Encoding.UTF8.GetString(tokenData);
var dataParts = dataString.Split(':');
if (dataParts.Length != 3)
{
return false;
}
username = dataParts[0];
var timestamp = DateTime.Parse(dataParts[2]);
// Check if token is not older than 8 hours
if (DateTime.UtcNow - timestamp > TimeSpan.FromHours(8))
{
return false;
}
return true;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to validate session token");
return false;
}
}
private bool cryptographicEqual(byte[] a, byte[] b)
{
if (a.Length != b.Length)
return false;
int result = 0;
for (int i = 0; i < a.Length; i++)
{
result |= a[i] ^ b[i];
}
return result == 0;
}
/// <summary>
/// Get password policy information
/// </summary>
public async Task<PasswordPolicy> GetPasswordPolicyAsync()
{
try
{
using (var directoryEntry = new DirectoryEntry(_ldapPath))
using (var directorySearcher = new DirectorySearcher(directoryEntry))
{
directorySearcher.Filter = "(objectClass=domainDNS)";
directorySearcher.PropertiesToLoad.AddRange(new[]
{
"minPwdLength", "maxPwdAge", "minPwdAge", "pwdHistoryLength", "pwdProperties"
});
var result = directorySearcher.FindOne();
if (result != null)
{
var policy = new PasswordPolicy();
if (result.Properties.Contains("minPwdLength"))
policy.MinLength = Convert.ToInt32(result.Properties["minPwdLength"][0]);
if (result.Properties.Contains("maxPwdAge"))
{
var maxAge = Convert.ToInt64(result.Properties["maxPwdAge"][0]);
policy.MaxAge = maxAge > 0 ? TimeSpan.FromTicks(-maxAge) : TimeSpan.Zero;
}
if (result.Properties.Contains("minPwdAge"))
{
var minAge = Convert.ToInt64(result.Properties["minPwdAge"][0]);
policy.MinAge = minAge > 0 ? TimeSpan.FromTicks(-minAge) : TimeSpan.Zero;
}
if (result.Properties.Contains("pwdHistoryLength"))
policy.HistoryLength = Convert.ToInt32(result.Properties["pwdHistoryLength"][0]);
return policy;
}
}
return new PasswordPolicy(); // Default policy
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to get password policy");
return new PasswordPolicy();
}
}
public void Dispose()
{
_context?.Dispose();
}
}
// Data models
public class AuthenticationResult
{
public bool Success { get; set; }
public string ErrorMessage { get; set; }
public UserInfo User { get; set; }
public string SessionToken { get; set; }
public DateTime ExpiresAt { get; set; }
}
public class UserInfo
{
public string Username { get; set; }
public string DisplayName { get; set; }
public string EmailAddress { get; set; }
public string GivenName { get; set; }
public string Surname { get; set; }
public string Title { get; set; }
public string Department { get; set; }
public string Company { get; set; }
public string Office { get; set; }
public string TelephoneNumber { get; set; }
public string MobilePhone { get; set; }
public string Manager { get; set; }
public string EmployeeId { get; set; }
public string DistinguishedName { get; set; }
public string UserPrincipalName { get; set; }
public bool Enabled { get; set; }
public DateTime? LastLogon { get; set; }
public DateTime? PasswordLastSet { get; set; }
public DateTime? AccountExpirationDate { get; set; }
public List<string> Groups { get; set; } = new List<string>();
}
public class PasswordPolicy
{
public int MinLength { get; set; } = 8;
public TimeSpan MaxAge { get; set; } = TimeSpan.FromDays(42);
public TimeSpan MinAge { get; set; } = TimeSpan.Zero;
public int HistoryLength { get; set; } = 12;
}
public class ActiveDirectoryException : Exception
{
public ActiveDirectoryException(string message) : base(message) { }
public ActiveDirectoryException(string message, Exception innerException) : base(message, innerException) { }
}
public class UserNotFoundException : Exception
{
public UserNotFoundException(string message) : base(message) { }
}
// Program.cs example usage
/*
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args);
// Add services
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Add Active Directory service
builder.Services.AddSingleton<ActiveDirectoryService>();
var app = builder.Build();
// Configure HTTP request pipeline
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
// Controllers/AuthController.cs
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly ActiveDirectoryService _adService;
public AuthController(ActiveDirectoryService adService)
{
_adService = adService;
}
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] LoginRequest request)
{
try
{
var result = await _adService.AuthenticateUserAsync(request.Username, request.Password);
if (result.Success)
{
return Ok(new
{
success = true,
user = result.User,
token = result.SessionToken,
expiresAt = result.ExpiresAt
});
}
else
{
return BadRequest(new { success = false, error = result.ErrorMessage });
}
}
catch (Exception ex)
{
return StatusCode(500, new { success = false, error = "Authentication service unavailable" });
}
}
[HttpPost("validate")]
public async Task<IActionResult> ValidateToken([FromBody] TokenRequest request)
{
try
{
if (_adService.ValidateSessionToken(request.Token, out string username))
{
var userInfo = await _adService.GetUserInfoAsync(username);
return Ok(new { success = true, user = userInfo });
}
else
{
return Unauthorized(new { success = false, error = "Invalid or expired token" });
}
}
catch (Exception ex)
{
return StatusCode(500, new { success = false, error = "Validation failed" });
}
}
[HttpGet("users/search")]
public async Task<IActionResult> SearchUsers([FromQuery] string q, [FromQuery] int limit = 10)
{
try
{
var users = await _adService.SearchUsersAsync(q, limit);
return Ok(new { success = true, users = users });
}
catch (Exception ex)
{
return StatusCode(500, new { success = false, error = "Search failed" });
}
}
}
public class LoginRequest
{
public string Username { get; set; }
public string Password { get; set; }
}
public class TokenRequest
{
public string Token { get; set; }
}
*/
}
💻 LDAP User Management Operations java
🔴 complex
⭐⭐⭐⭐⭐
CRUD operations for managing users in LDAP directory services including create, update, delete, and password management
⏱️ 60 min
🏷️ ldap, java, user management, directory
Prerequisites:
LDAP concepts, Java programming, JNDI, Directory operations
package com.example.ldap;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;
import java.util.*;
import java.security.SecureRandom;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.regex.Pattern;
/**
* LDAP User Management Service
* Provides comprehensive CRUD operations for managing users in LDAP directory
*/
public class LDAPUserManager {
private static final String[] USER_ATTRIBUTES = {
"uid", "cn", "sn", "givenName", "mail", "telephoneNumber",
"departmentNumber", "employeeType", "description", "memberOf"
};
private final LdapContext context;
private final String baseDN;
private final String userContainer;
private final SecureRandom random = new SecureRandom();
public LDAPUserManager(LDAPConfig config) throws NamingException {
this.baseDN = config.getBaseDN();
this.userContainer = config.getUserContainer();
// Create initial directory context
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, config.getLdapUrl());
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, config.getBindDN());
env.put(Context.SECURITY_CREDENTIALS, config.getBindPassword());
// Enable connection pooling
env.put("com.sun.jndi.ldap.connect.pool", "true");
env.put("com.sun.jndi.ldap.connect.pool.protocol", "ssl");
env.put("com.sun.jndi.ldap.connect.pool.maxsize", "10");
// Set timeout values
env.put("com.sun.jndi.ldap.connect.timeout", "5000");
env.put("com.sun.jndi.ldap.read.timeout", "10000");
// Enable TLS if configured
if (config.isUseTLS()) {
env.put(Context.SECURITY_PROTOCOL, "ssl");
env.put("java.naming.ldap.factory.socket",
"com.example.ldap.CustomSSLSocketFactory");
}
this.context = new InitialLdapContext(env, null);
System.out.println("Connected to LDAP server: " + config.getLdapUrl());
}
/**
* Create a new user in LDAP
*/
public User createUser(CreateUserRequest request) throws LDAPException {
try {
// Validate input
validateUserRequest(request);
// Check if user already exists
if (userExists(request.getUid())) {
throw new LDAPException("User with UID '" + request.getUid() + "' already exists");
}
// Build user DN
String userDN = String.format("uid=%s,%s", request.getUid(), userContainer);
// Create user attributes
Attributes attributes = new BasicAttributes(true);
Attribute oc = new BasicAttribute("objectClass");
oc.add("top");
oc.add("person");
oc.add("organizationalPerson");
oc.add("inetOrgPerson");
attributes.put(oc);
// Set required attributes
attributes.put(new BasicAttribute("uid", request.getUid()));
attributes.put(new BasicAttribute("cn", request.getCn()));
attributes.put(new BasicAttribute("sn", request.getSn()));
// Set optional attributes
setOptionalAttribute(attributes, "givenName", request.getGivenName());
setOptionalAttribute(attributes, "mail", request.getMail());
setOptionalAttribute(attributes, "telephoneNumber", request.getTelephoneNumber());
setOptionalAttribute(attributes, "departmentNumber", request.getDepartmentNumber());
setOptionalAttribute(attributes, "employeeType", request.getEmployeeType());
setOptionalAttribute(attributes, "description", request.getDescription());
// Set password
String hashedPassword = hashPassword(request.getPassword());
attributes.put(new BasicAttribute("userPassword", hashedPassword));
// Create the user entry
context.createSubcontext(userDN, attributes);
System.out.println("Created user: " + userDN);
// Return created user information
return getUser(request.getUid());
} catch (NamingException e) {
throw new LDAPException("Failed to create user: " + e.getMessage(), e);
}
}
/**
* Get user information
*/
public User getUser(String uid) throws LDAPException {
try {
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
controls.setReturningAttributes(USER_ATTRIBUTES);
controls.setCountLimit(1);
String filter = String.format("(uid=%s)", escapeLDAPSearchFilter(uid));
NamingEnumeration<SearchResult> results = context.search(
baseDN, filter, controls);
if (results.hasMore()) {
SearchResult result = results.next();
return mapSearchResultToUser(result);
} else {
throw new UserNotFoundException("User not found: " + uid);
}
} catch (NamingException e) {
throw new LDAPException("Failed to get user: " + e.getMessage(), e);
}
}
/**
* Update user information
*/
public User updateUser(String uid, UpdateUserRequest request) throws LDAPException {
try {
// Check if user exists
if (!userExists(uid)) {
throw new UserNotFoundException("User not found: " + uid);
}
String userDN = String.format("uid=%s,%s", uid, userContainer);
// Build modification list
List<ModificationItem> modifications = new ArrayList<>();
// Update attributes
updateAttribute(modifications, "cn", request.getCn());
updateAttribute(modifications, "sn", request.getSn());
updateAttribute(modifications, "givenName", request.getGivenName());
updateAttribute(modifications, "mail", request.getMail());
updateAttribute(modifications, "telephoneNumber", request.getTelephoneNumber());
updateAttribute(modifications, "departmentNumber", request.getDepartmentNumber());
updateAttribute(modifications, "employeeType", request.getEmployeeType());
updateAttribute(modifications, "description", request.getDescription());
// Apply modifications if any
if (!modifications.isEmpty()) {
ModificationItem[] mods = modifications.toArray(new ModificationItem[0]);
context.modifyAttributes(userDN, mods);
}
System.out.println("Updated user: " + uid);
// Return updated user information
return getUser(uid);
} catch (NamingException e) {
throw new LDAPException("Failed to update user: " + e.getMessage(), e);
}
}
/**
* Delete user from LDAP
*/
public void deleteUser(String uid) throws LDAPException {
try {
if (!userExists(uid)) {
throw new UserNotFoundException("User not found: " + uid);
}
String userDN = String.format("uid=%s,%s", uid, userContainer);
context.destroySubcontext(userDN);
System.out.println("Deleted user: " + uid);
} catch (NamingException e) {
throw new LDAPException("Failed to delete user: " + e.getMessage(), e);
}
}
/**
* Change user password
*/
public void changePassword(String uid, String newPassword) throws LDAPException {
try {
if (!userExists(uid)) {
throw new UserNotFoundException("User not found: " + uid);
}
// Validate password strength
validatePassword(newPassword);
String userDN = String.format("uid=%s,%s", uid, userContainer);
// Create password modification
ModificationItem[] mods = new ModificationItem[1];
Attribute passwordAttr = new BasicAttribute("userPassword", hashPassword(newPassword));
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, passwordAttr);
context.modifyAttributes(userDN, mods);
System.out.println("Password changed for user: " + uid);
} catch (NamingException e) {
throw new LDAPException("Failed to change password: " + e.getMessage(), e);
}
}
/**
* Enable or disable user account
*/
public void setUserStatus(String uid, boolean enabled) throws LDAPException {
try {
if (!userExists(uid)) {
throw new UserNotFoundException("User not found: " + uid);
}
String userDN = String.format("uid=%s,%s", uid, userContainer);
// Some LDAP servers use different attributes for account status
// This implementation assumes the use of pwdAccountLockedTime
String lockValue = enabled ? "000001010000Z" : null;
ModificationItem[] mods = new ModificationItem[1];
Attribute lockAttr = new BasicAttribute("pwdAccountLockedTime", lockValue);
if (enabled) {
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, lockAttr);
} else {
mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, lockAttr);
}
context.modifyAttributes(userDN, mods);
System.out.println("User status changed: " + uid + " -> " + (enabled ? "enabled" : "disabled"));
} catch (NamingException e) {
throw new LDAPException("Failed to change user status: " + e.getMessage(), e);
}
}
/**
* Search for users
*/
public List<User> searchUsers(SearchRequest request) throws LDAPException {
try {
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
controls.setReturningAttributes(USER_ATTRIBUTES);
controls.setCountLimit(request.getLimit() > 0 ? request.getLimit() : 100);
// Build search filter
StringBuilder filter = new StringBuilder("(&(objectClass=inetOrgPerson)");
if (request.getUid() != null) {
filter.append(String.format("(uid=*%s*)", escapeLDAPSearchFilter(request.getUid())));
}
if (request.getCn() != null) {
filter.append(String.format("(cn=*%s*)", escapeLDAPSearchFilter(request.getCn())));
}
if (request.getMail() != null) {
filter.append(String.format("(mail=*%s*)", escapeLDAPSearchFilter(request.getMail())));
}
if (request.getDepartmentNumber() != null) {
filter.append(String.format("(departmentNumber=*%s*)", escapeLDAPSearchFilter(request.getDepartmentNumber())));
}
filter.append(")");
NamingEnumeration<SearchResult> results = context.search(
baseDN, filter.toString(), controls);
List<User> users = new ArrayList<>();
while (results.hasMore()) {
SearchResult result = results.next();
users.add(mapSearchResultToUser(result));
}
return users;
} catch (NamingException e) {
throw new LDAPException("Failed to search users: " + e.getMessage(), e);
}
}
/**
* Get user groups
*/
public List<String> getUserGroups(String uid) throws LDAPException {
try {
String userDN = String.format("uid=%s,%s", uid, userContainer);
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
controls.setReturningAttributes(new String[]{"cn"});
String filter = String.format("(&(objectClass=groupOfNames)(member=%s))", escapeLDAPSearchFilter(userDN));
NamingEnumeration<SearchResult> results = context.search(baseDN, filter, controls);
List<String> groups = new ArrayList<>();
while (results.hasMore()) {
SearchResult result = results.next();
Attribute cnAttr = result.getAttributes().get("cn");
if (cnAttr != null) {
groups.add(cnAttr.get().toString());
}
}
return groups;
} catch (NamingException e) {
throw new LDAPException("Failed to get user groups: " + e.getMessage(), e);
}
}
/**
* Add user to group
*/
public void addUserToGroup(String uid, String groupCn) throws LDAPException {
try {
if (!userExists(uid)) {
throw new UserNotFoundException("User not found: " + uid);
}
String userDN = String.format("uid=%s,%s", uid, userContainer);
String groupDN = String.format("cn=%s,ou=groups,%s", groupCn, baseDN);
// Add user to group
ModificationItem[] mods = new ModificationItem[1];
Attribute memberAttr = new BasicAttribute("member", userDN);
mods[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE, memberAttr);
context.modifyAttributes(groupDN, mods);
System.out.println("Added user " + uid + " to group " + groupCn);
} catch (NamingException e) {
throw new LDAPException("Failed to add user to group: " + e.getMessage(), e);
}
}
/**
* Remove user from group
*/
public void removeUserFromGroup(String uid, String groupCn) throws LDAPException {
try {
String userDN = String.format("uid=%s,%s", uid, userContainer);
String groupDN = String.format("cn=%s,ou=groups,%s", groupCn, baseDN);
// Remove user from group
ModificationItem[] mods = new ModificationItem[1];
Attribute memberAttr = new BasicAttribute("member", userDN);
mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, memberAttr);
context.modifyAttributes(groupDN, mods);
System.out.println("Removed user " + uid + " from group " + groupCn);
} catch (NamingException e) {
throw new LDAPException("Failed to remove user from group: " + e.getMessage(), e);
}
}
// Helper methods
private boolean userExists(String uid) throws LDAPException {
try {
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
controls.setCountLimit(1);
String filter = String.format("(uid=%s)", escapeLDAPSearchFilter(uid));
NamingEnumeration<SearchResult> results = context.search(baseDN, filter, controls);
return results.hasMore();
} catch (NamingException e) {
throw new LDAPException("Failed to check user existence: " + e.getMessage(), e);
}
}
private void validateUserRequest(CreateUserRequest request) throws LDAPException {
if (request.getUid() == null || request.getUid().trim().isEmpty()) {
throw new LDAPException("UID is required");
}
if (request.getCn() == null || request.getCn().trim().isEmpty()) {
throw new LDAPException("Common name (CN) is required");
}
if (request.getSn() == null || request.getSn().trim().isEmpty()) {
throw new LDAPException("Surname (SN) is required");
}
if (request.getPassword() == null || request.getPassword().trim().isEmpty()) {
throw new LDAPException("Password is required");
}
validatePassword(request.getPassword());
}
private void validatePassword(String password) throws LDAPException {
if (password == null || password.length() < 8) {
throw new LDAPException("Password must be at least 8 characters long");
}
// Check for password complexity
if (!Pattern.compile("[A-Z]").matcher(password).find()) {
throw new LDAPException("Password must contain at least one uppercase letter");
}
if (!Pattern.compile("[a-z]").matcher(password).find()) {
throw new LDAPException("Password must contain at least one lowercase letter");
}
if (!Pattern.compile("[0-9]").matcher(password).find()) {
throw new LDAPException("Password must contain at least one digit");
}
}
private String hashPassword(String password) {
// This is a simplified implementation
// In production, use a proper password hashing library
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest(password.getBytes());
return Base64.getEncoder().encodeToString(hash);
} catch (Exception e) {
throw new RuntimeException("Failed to hash password", e);
}
}
private void setOptionalAttribute(Attributes attributes, String name, String value) {
if (value != null && !value.trim().isEmpty()) {
attributes.put(new BasicAttribute(name, value));
}
}
private void updateAttribute(List<ModificationItem> modifications, String name, String value) {
if (value != null) {
Attribute attr = new BasicAttribute(name, value);
modifications.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attr));
}
}
private User mapSearchResultToUser(SearchResult result) throws NamingException {
Attributes attrs = result.getAttributes();
User user = new User();
user.setDn(result.getNameInNamespace());
user.setUid(getAttributeValue(attrs, "uid"));
user.setCn(getAttributeValue(attrs, "cn"));
user.setSn(getAttributeValue(attrs, "sn"));
user.setGivenName(getAttributeValue(attrs, "givenName"));
user.setMail(getAttributeValue(attrs, "mail"));
user.setTelephoneNumber(getAttributeValue(attrs, "telephoneNumber"));
user.setDepartmentNumber(getAttributeValue(attrs, "departmentNumber"));
user.setEmployeeType(getAttributeValue(attrs, "employeeType"));
user.setDescription(getAttributeValue(attrs, "description"));
return user;
}
private String getAttributeValue(Attributes attrs, String name) throws NamingException {
Attribute attr = attrs.get(name);
if (attr != null) {
Object value = attr.get();
return value != null ? value.toString() : null;
}
return null;
}
private String escapeLDAPSearchFilter(String filter) {
if (filter == null) return "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < filter.length(); i++) {
char c = filter.charAt(i);
switch (c) {
case '\\':
sb.append("\\5c");
break;
case '*':
sb.append("\\2a");
break;
case '(':
sb.append("\\28");
break;
case ')':
sb.append("\\29");
break;
case '\u0000':
sb.append("\\00");
break;
default:
sb.append(c);
}
}
return sb.toString();
}
/**
* Close LDAP context
*/
public void close() {
try {
if (context != null) {
context.close();
}
} catch (NamingException e) {
System.err.println("Error closing LDAP context: " + e.getMessage());
}
}
}
// Data classes
class LDAPConfig {
private String ldapUrl;
private String baseDN;
private String userContainer;
private String bindDN;
private String bindPassword;
private boolean useTLS;
// Getters and setters
public String getLdapUrl() { return ldapUrl; }
public String getBaseDN() { return baseDN; }
public String getUserContainer() { return userContainer; }
public String getBindDN() { return bindDN; }
public String getBindPassword() { return bindPassword; }
public boolean isUseTLS() { return useTLS; }
// Builder pattern
public static class Builder {
private LDAPConfig config = new LDAPConfig();
public Builder ldapUrl(String ldapUrl) { config.ldapUrl = ldapUrl; return this; }
public Builder baseDN(String baseDN) { config.baseDN = baseDN; return this; }
public Builder userContainer(String userContainer) { config.userContainer = userContainer; return this; }
public Builder bindDN(String bindDN) { config.bindDN = bindDN; return this; }
public Builder bindPassword(String bindPassword) { config.bindPassword = bindPassword; return this; }
public Builder useTLS(boolean useTLS) { config.useTLS = useTLS; return this; }
public LDAPConfig build() { return config; }
}
}
class User {
private String dn;
private String uid;
private String cn;
private String sn;
private String givenName;
private String mail;
private String telephoneNumber;
private String departmentNumber;
private String employeeType;
private String description;
// Getters and setters
public String getDn() { return dn; }
public void setDn(String dn) { this.dn = dn; }
public String getUid() { return uid; }
public void setUid(String uid) { this.uid = uid; }
public String getCn() { return cn; }
public void setCn(String cn) { this.cn = cn; }
public String getSn() { return sn; }
public void setSn(String sn) { this.sn = sn; }
public String getGivenName() { return givenName; }
public void setGivenName(String givenName) { this.givenName = givenName; }
public String getMail() { return mail; }
public void setMail(String mail) { this.mail = mail; }
public String getTelephoneNumber() { return telephoneNumber; }
public void setTelephoneNumber(String telephoneNumber) { this.telephoneNumber = telephoneNumber; }
public String getDepartmentNumber() { return departmentNumber; }
public void setDepartmentNumber(String departmentNumber) { this.departmentNumber = departmentNumber; }
public String getEmployeeType() { return employeeType; }
public void setEmployeeType(String employeeType) { this.employeeType = employeeType; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
}
class CreateUserRequest {
private String uid;
private String cn;
private String sn;
private String givenName;
private String mail;
private String telephoneNumber;
private String departmentNumber;
private String employeeType;
private String description;
private String password;
// Getters and setters
public String getUid() { return uid; }
public String getCn() { return cn; }
public String getSn() { return sn; }
public String getGivenName() { return givenName; }
public String getMail() { return mail; }
public String getTelephoneNumber() { return telephoneNumber; }
public String getDepartmentNumber() { return departmentNumber; }
public String getEmployeeType() { return employeeType; }
public String getDescription() { return description; }
public String getPassword() { return password; }
// Setters...
public void setUid(String uid) { this.uid = uid; }
public void setCn(String cn) { this.cn = cn; }
public void setSn(String sn) { this.sn = sn; }
public void setGivenName(String givenName) { this.givenName = givenName; }
public void setMail(String mail) { this.mail = mail; }
public void setTelephoneNumber(String telephoneNumber) { this.telephoneNumber = telephoneNumber; }
public void setDepartmentNumber(String departmentNumber) { this.departmentNumber = departmentNumber; }
public void setEmployeeType(String employeeType) { this.employeeType = employeeType; }
public void setDescription(String description) { this.description = description; }
public void setPassword(String password) { this.password = password; }
}
class UpdateUserRequest {
private String cn;
private String sn;
private String givenName;
private String mail;
private String telephoneNumber;
private String departmentNumber;
private String employeeType;
private String description;
// Getters and setters...
public String getCn() { return cn; }
public String getSn() { return sn; }
public String getGivenName() { return givenName; }
public String getMail() { return mail; }
public String getTelephoneNumber() { return telephoneNumber; }
public String getDepartmentNumber() { return departmentNumber; }
public String getEmployeeType() { return employeeType; }
public String getDescription() { return description; }
public void setCn(String cn) { this.cn = cn; }
public void setSn(String sn) { this.sn = sn; }
public void setGivenName(String givenName) { this.givenName = givenName; }
public void setMail(String mail) { this.mail = mail; }
public void setTelephoneNumber(String telephoneNumber) { this.telephoneNumber = telephoneNumber; }
public void setDepartmentNumber(String departmentNumber) { this.departmentNumber = departmentNumber; }
public void setEmployeeType(String employeeType) { this.employeeType = employeeType; }
public void setDescription(String description) { this.description = description; }
}
class SearchRequest {
private String uid;
private String cn;
private String mail;
private String departmentNumber;
private int limit;
// Getters and setters...
public String getUid() { return uid; }
public String getCn() { return cn; }
public String getMail() { return mail; }
public String getDepartmentNumber() { return departmentNumber; }
public int getLimit() { return limit; }
public void setUid(String uid) { this.uid = uid; }
public void setCn(String cn) { this.cn = cn; }
public void setMail(String mail) { this.mail = mail; }
public void setDepartmentNumber(String departmentNumber) { this.departmentNumber = departmentNumber; }
public void setLimit(int limit) { this.limit = limit; }
}
class LDAPException extends Exception {
public LDAPException(String message) { super(message); }
public LDAPException(String message, Throwable cause) { super(message, cause); }
}
class UserNotFoundException extends LDAPException {
public UserNotFoundException(String message) { super(message); }
}
// Example usage
/*
public class LDAPExample {
public static void main(String[] args) {
try {
// Configure LDAP
LDAPConfig config = new LDAPConfig.Builder()
.ldapUrl("ldap://localhost:389")
.baseDN("dc=example,dc=com")
.userContainer("ou=users,dc=example,dc=com")
.bindDN("cn=admin,dc=example,dc=com")
.bindPassword("admin_password")
.useTLS(false)
.build();
// Create user manager
LDAPUserManager userManager = new LDAPUserManager(config);
try {
// Create a new user
CreateUserRequest createRequest = new CreateUserRequest();
createRequest.setUid("jdoe");
createRequest.setCn("John Doe");
createRequest.setSn("Doe");
createRequest.setGivenName("John");
createRequest.setMail("[email protected]");
createRequest.setTelephoneNumber("+1-555-0123");
createRequest.setDepartmentNumber("IT");
createRequest.setEmployeeType("Full-time");
createRequest.setDescription("New employee");
createRequest.setPassword("SecureP@ss123");
User createdUser = userManager.createUser(createRequest);
System.out.println("Created user: " + createdUser.getUid());
// Get user
User user = userManager.getUser("jdoe");
System.out.println("Retrieved user: " + user.getDisplayName());
// Update user
UpdateUserRequest updateRequest = new UpdateUserRequest();
updateRequest.setTelephoneNumber("+1-555-0456");
updateRequest.setDescription("Updated employee");
User updatedUser = userManager.updateUser("jdoe", updateRequest);
System.out.println("Updated user phone: " + updatedUser.getTelephoneNumber());
// Search users
SearchRequest searchRequest = new SearchRequest();
searchRequest.setDepartmentNumber("IT");
searchRequest.setLimit(10);
List<User> users = userManager.searchUsers(searchRequest);
System.out.println("Found " + users.size() + " users in IT department");
// Add user to group
userManager.addUserToGroup("jdoe", "developers");
// Get user groups
List<String> groups = userManager.getUserGroups("jdoe");
System.out.println("User groups: " + groups);
} finally {
userManager.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
*/