如何用ldap3搭建模拟AD服务器并跨Shell测试认证?
问题解答
首先明确:ldap3的MOCK_SYNC/MOCK_ASYNC模式做不到跨Shell的模拟AD服务。因为这种模拟是客户端本地内存级别的模拟,它并没有在本地启动一个真实的、可通过网络访问的LDAP服务器进程,所有操作都局限在当前Python进程内,没法被其他Shell的进程连接访问。
针对你的Django AD认证测试需求,这里给几个可行的方案:
方案1:用OpenLDAP搭建本地测试服务(真实LDAP环境)
这是最接近真实AD的测试方式,能完全模拟跨进程/Shell的认证场景:
- 如果你有Docker,可以快速启动一个OpenLDAP容器:
docker run -p 389:389 -e LDAP_ADMIN_PASSWORD=admin123 -e LDAP_DOMAIN=test.local -d osixia/openldap - 然后用ldap3连接这个服务,添加测试用户(在第一个Shell里执行):
from ldap3 import Server, Connection, ALL # 连接本地OpenLDAP服务 server = Server('localhost', get_info=ALL) conn = Connection(server, 'cn=admin,dc=test,dc=local', 'admin123', auto_bind=True) # 添加测试用户组织单元 conn.add('ou=users,dc=test,dc=local', 'organizationalUnit') # 添加测试用户 conn.add( 'cn=testuser,ou=users,dc=test,dc=local', 'inetOrgPerson', {'sn': 'Test', 'givenName': 'User', 'userPassword': 'testpass123'} ) conn.unbind() - 接着在第二个Shell里测试认证:
from ldap3 import Server, Connection server = Server('localhost') # 用测试用户密码尝试绑定 conn = Connection(server, 'cn=testuser,ou=users,dc=test,dc=local', 'testpass123') if conn.bind(): print('认证成功') else: print('认证失败') conn.unbind()
方案2:在Django测试用例中直接用ldap3客户端模拟
如果只是想在单元测试阶段验证认证逻辑,不需要跨Shell,可以直接在测试代码里用ldap3的模拟模式:
from django.test import TestCase from ldap3 import Server, Connection, OFFLINE_AD_2012_R2, MOCK_SYNC class ADAuthTestCase(TestCase): def test_ad_authentication(self): # 初始化模拟AD连接 mock_server = Server('dummy_ad', get_info=OFFLINE_AD_2012_R2) mock_conn = Connection(mock_server, client_strategy=MOCK_SYNC) mock_conn.bind() # 添加模拟测试用户 mock_conn.add( 'cn=testuser,ou=Users,dc=dummy,dc=ad', 'user', {'userPrincipalName': 'testuser@dummy.ad', 'sAMAccountName': 'testuser', 'unicodePwd': '"testpass123"'} ) # 模拟你的Django AD认证逻辑 def ad_authenticate(username, password): test_conn = Connection(mock_server, f'cn={username},ou=Users,dc=dummy,dc=ad', password, client_strategy=MOCK_SYNC) return test_conn.bind() # 验证正确/错误密码的认证结果 self.assertTrue(ad_authenticate('testuser', 'testpass123')) self.assertFalse(ad_authenticate('testuser', 'wrongpass'))
方案3:用Python启动简易LDAP服务器
可以用ldapserver库(提前执行pip install ldapserver安装)写一个简单的LDAP服务器,在一个Shell启动后,另一个Shell可连接测试:
# 第一个Shell运行的服务器代码 from ldapserver import Server, BaseHandler from ldapserver.protocols.ldap import operations class TestADHandler(BaseHandler): def bind(self, request, controls): username = request.name.decode() password = request.authentication.decode() # 模拟用户密码验证逻辑 if username == 'testuser@dummy.ad' and password == 'testpass123': return operations.BindResponse(result_code=0) else: return operations.BindResponse(result_code=49) if __name__ == '__main__': server = Server(('localhost', 3890), TestADHandler) print('模拟AD服务器启动在3890端口') server.serve_forever()
然后在第二个Shell里连接测试:
from ldap3 import Server, Connection server = Server('localhost', port=3890) conn = Connection(server, 'testuser@dummy.ad', 'testpass123') if conn.bind(): print('认证成功') else: print('认证失败')
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

