python使用ldap進行用戶認證


這兩天做sso,用到了ldap,這個東西只見過沒涉及過,最近還是看了小兩天,記錄一下

LDAP輕型目錄訪問協議,可以就把他看成一個輕量級數據庫,那么現在系統已經有mysql等數據庫了,為什么還要用這個,有兩個原因:
1.ldap server使用的是tree結構,查詢很快
2.ldap協議比較通用,很多語言和環境對他有支持,方便不同語言及環境間的對接

包版本ldap3==2.9.1
這個東西django其實有一個專門的第三方庫,配置一下就行了,但是目前架構沒有使用django自帶的用戶系統,所以不好適配就直接手寫了

from ldap3 import Server, Connection, ALL, MODIFY_ADD, MODIFY_REPLACE, MODIFY_DELETE


class Connect_ldap:

    def __init__(self):  # 初始化
        self.server = '127.0.0.1'  # ldap服務器地址
        self.user = 'cn=admin,dc=XXX,dc=com'  # Bind DN or user
        self.base_dn = 'dc=XXX,dc=com'  # base_dn
        self.pwd = 'XXXXX'  # 密碼
        self.port = 389  # 端口

    def connect(self):  # 連接ldap服務
        server = Server(host=self.server, port=self.port, get_info=ALL)
        conn = Connection(server=server, user=self.user, password=self.pwd, auto_bind=True)
        return conn

    def get_user(self) -> bool:
        """
        用戶查詢
        :return:
        """
        conn = self.connect()
        dn_look_path = 'ou=Users,dc=XXX,dc=com'
        find_res = conn.search(dn_look_path,
                               '(&(cn=xxxx)(userPassword=xxxxx))')  # cn is username && userPassword is password
        return find_res

    def add_user(self, username, password) -> bool:
        """
        用戶添加
        :param username: 用戶名
        :param password: 密碼
        :return:
        """
        conn = self.connect()
        add_res = conn.add(f"cn={username},ou=Users,dc=XXX,dc=com",
                           object_class=['inetOrgPerson', 'top'],  # 類型
                           attributes={'sn': username, 'userPassword': password})  # 屬性
        return add_res

    def delete_user(self, username):
        """
        用戶刪除
        :param username
        :return:
        """
        conn = self.connect()
        delete_res = conn.delete(f"cn={username},ou=Users,dc=XXX,dc=com")
        return delete_res

    def modify_user(self, username, password) -> bool:
        """
        用戶修改密碼
        :param username:
        :param password:
        :return:
        """
        conn = self.connect()
        modify_res = conn.modify(f"cn={username},ou=Users,dc=XXX,dc=com",
                                 {"userPassword": [(MODIFY_REPLACE, [password])]})
        return modify_res


if __name__ == "__main__":
    a = Connect_ldap()
    res = a.add_user('xxxx2', '123456')
    print(res)

上面這個類就大致是對接ldap代碼了,涉及到用戶的增刪改查
當然這里ldap是為了sso,也就是其它系統的免登錄操作,所以自身用戶系統的數據庫還是少不了了

ldap server的話我是用docker直接拉下來的,也比較方便

docker run -itd --privileged=true --net=host --name my-ldap \
-v /home/xxx_ldap/database:/var/lib/ldap \
-v /home/xxx_ldap/config:/etc/ldap/slapd.d \
--env LDAP_ORGANISATION="XXX" \
--env LDAP_DOMAIN="XXX.com" \
--env LDAP_ADMIN_PASSWORD="XXXXX" \
--detach osixia/openldap:latest

ldap管理也是docker拉的

docker run -d --privileged=true --net=host --name my-phpldapadmin \
--env PHPLDAPADMIN_HTTPS=true \
--env PHPLDAPADMIN_LDAP_HOSTS=127.0.0.1 \
--detach osixia/phpldapadmin

這里80端口給占了,改成81還是沒法訪問,用https可以了,應該是PHPLDAPADMIN_HTTPS參數的事情
登錄進去后創建ou,這里ou是Users,具體創建參照這個大佬

以下是系統(前后端分離模式)的ldap流程:

1.首先將用戶輸入賬號、密碼信息發給ldap服務器進行認證
2.如果ldap認證通過,我們去查詢數據庫中是否已存在此賬號的用戶,若存在,進行權限校驗等操作,若不存在,則先在數據庫中創建此用戶,隨后直接登陸
3.如果ldap認證失敗,返回錯誤即可

感覺可能敘述的還不太清楚,因為本身資料就非常零碎,找了好多有些都忘了在哪看的,如果有疑問的話可以留言


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM