天天看点

Django实现AD域集成Python实现AD域集成

Python实现AD域集成

本片文章简单介绍一下django项目中的AD域集成业务逻辑实现。

AD域

  • “AD域可用于同时管理多台电脑,这样实现集中式管理,可以很大程度减少管理员的工作量。比如曾经我们需要在无数客户端上进行多次的设置,在AD域控制器上只需要设置一次就能完成。”

实现过程

  1. 使用第三方工具:

    ldap

    这是一种通信协议。
  2. 安装python-ldap,不同的环境使用的ldap不同,python2.7和python3.7略有不同。
  3. 了解ldap增删改查
查找和读取一条 LDAP 纪录,比如根据 username 查找出 cn:
def ldap_getcn(username):
    try:
        l = ldap.open(LDAP_HOST)
        l.protocol_version = ldap.VERSION3
        l.simple_bind(LDAP_BIND, LDAP_PASS)

        searchScope = ldap.SCOPE_SUBTREE
        searchFilter = "uid=*" + username + "*"
        resultID = l.search(LDAP_BASE, searchScope, searchFilter, None)
        result_set = []
        while 1:
            result_type, result_data = l.result(resultID, 0)
            if (result_data == []):
                break
            else:
                if result_type == ldap.RES_SEARCH_ENTRY:
                    result_set.append(result_data)
        return result_set[0][0][1]['cn'][0]
    except ldap.LDAPError, e:
        print e
        
更新一条 LDAP 纪录,比如更新用户状态 active 为 false:
def ldap_deactive(username):
    try:
        l = ldap.open(LDAP_HOST)
        l.protocol_version = ldap.VERSION3
        l.simple_bind(LDAP_BIND, LDAP_PASS)

        deactiveDN = ("cn=%s," + LDAP_BASE) % ldap_getcn(username)
        old = {'active':'TRUE'}
        new = {'active':'FALSE'}
        ldif = modlist.modifyModlist(old, new)
        l.modify_s(deactiveDN, ldif)
        l.unbind_s()
    except ldap.LDAPError, e:
        print e   
             
删除一条 LDAP 纪录:
def ldap_delete(username):
    try:
        l = ldap.open(LDAP_HOST)
        l.protocol_version = ldap.VERSION3
        l.simple_bind(LDAP_BIND, LDAP_PASS)

        deleteDN = ("cn=%s," + LDAP_BASE) % ldap_getcn(username)
        l.delete_s(deleteDN)
    except ldap.LDAPError, e:
        print e        
           
  1. 了解使用方法之后,做一些用户验证,验证成功后将数据保存。
一个简单的验证,django登陆是调用就可以。
import ldap
 
class LDAPBackend(object):
    """
    Authenticates with ldap.
    """
    _connection = None
    _connection_bound = False
 
    def authenticate(self, username=None, passwd=None, **kwargs):
        if not username or not passwd:
            return None
        if self._authenticate_user_dn(username, passwd):
            user = self._get_or_create_user(username, passwd)
            return user
        else:
            return None
 
    @property
    def connection(self):
        if not self._connection_bound:
            self._bind()
        return self._get_connection()
 
    def _bind(self):
        self._bind_as(
            LDAP_CONFIG['USERNAME'], LDAP_CONFIG['PASSWORD'], True
        )
 
    def _bind_as(self, bind_dn, bind_password, sticky=False):
        self._get_connection().simple_bind_s(
            bind_dn, bind_password
        )
        self._connection_bound = sticky
 
    def _get_connection(self):
        if not self._connection:
            self._connection = ldap.initialize(LDAP_CONFIG['HOST'])
        return self._connection
 
    def _authenticate_user_dn(self, username, passwd):
        bind_dn = 'cn=%s,%s' % (username, LDAP_CONFIG['BASE_DN'])
        try:
            self._bind_as(bind_dn, passwd, False)
            return True
        except ldap.INVALID_CREDENTIALS:
            return False
 
    def _get_or_create_user(self, username, passwd):
        # 获取或者新建User
        return user
           

具体保存什么数据,验证方式还需要业务逻辑.