基于Python + Django 的密码自助平台项目(完整代码)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
场景说明
因为本公司 AD 是早期已经在用用户的个人信息不是十分全面例如:用户手机号。 钉钉是后来才开始使用钉钉默认是使用手机号登录。 用户自行重置密码时如果通过手机号来进行钉钉与 AD 之间的验证就行不通了。
逻辑
用户扫码通过之后通过临时授权码提取用户的 userid再通过 userid 断用户在本企业中是否存在。如果存在提取钉钉/企业微信用户的邮箱通过邮箱转成账号将账号拿到 AD 中进行比对来验证账号在 AD 中是否存在并账号状态是激活的。满足以上条件的账号就会视为可自行重置密码。
无论是钉钉、微信均是通过提取用户邮箱的前缀部分来作为关联 AD 的账号所以目前的识别逻辑就需要保证邮箱的前缀和 AD 的登录账号是一致的。 如果您的场景不是这样请按自己的需求修改源代码适配。
代码提交到--新分支
djaong3
提示
AD必须使用SSL才能修改密码这里被坑了N久...
自行部署下AD的证书服务并颁发CA证书重启服务器生效。
具体教程百度一下有很多。
本次升级、修复请使用最新版
升级 Python 版本为 3.8
升级 Django 到 3.2
修复用户名中使用\被转义的问题
重写了 dingding 模块因为 dingding 开发者平台接口鉴权的一些变动之前的一些接口不能再使用本次重写。
重写了 ad 模块修改账号的一些判断逻辑。
重写了用户账号的格式兼容现在用户账号可以兼容username、DOMAIN\username、username@abc.com 这三种格式。
优化了整体的代码逻辑去掉一些冗余重复的代码。
2021/05/19 -- 更新
添加了企业微信支持修改 pwdselfservice/local_settings.py 中的 SCAN_CODE_TYPE = 'DING'或 SCAN_CODE_TYPE = 'WEWORK'区分使用哪个应用扫码验证
添加 Reids 缓存 Token 支持如果不配置 Redis 则使用 MemoryStorage 缓存到内存中
Redis 的安装和配置方法请自行百度比较简单
切记 Redis 一定请配置密码弱密码或没有密码的 Redis 如果不小心暴露到公网极其容易导致机器被黑用来挖矿。
整体验证逻辑不变如果需要使用其它字段关联到 AD 验证的请自行修改代码。
线上环境需要的基础环境
Python 3.8.9 (可自行下载源码包放到项目目录下使用一键安装)
Nginx
Uwsgi
截图
钉钉
微信
扫码成功之后
钉钉必要条件
创建企业内部应用
在钉钉工作台中通过“自建应用”创建应用选择“企业内部开发”创建 H5 微应用或小程序在应用首页中获取应用的AgentId、AppKey、AppSecret。
应用需要权限身份验证、消息通知、通讯录只读权限、手机号码信息、邮箱等个人信息、智能人事范围是全部员工或自行选择
应用安全域名和 IP 一定要配置否则无法返回接口数据。
参考截图配置
移动接入应用--登录权限
登录中开启扫码登录配置回调域名“ https://pwd.abc.com/callbackCheck” 其中 pwd.abc.com 请按自己实际域名来并记录相关的appId、appSecret。
参考截图配置
企业微信必要条件
创建应用记录下企业的 CorpId应用的 ID 和 Secret。
参考截图
飞书必要条件
开放平台--> 创建应--> 网页开启--> 配置回调 url
飞书接口项目地址 https://github.com/larksuite/feishu 感谢大佬节省了不少时间。
使用脚本自动部署
使用脚本自动快速部署只适合 CentOS其它发行版本的 Linux 请自行修改相关命令。
把整个项目目录上传到新的服务器上
先修改配置文件按自己实际的配置修改项目配置文件
修改 conf/local_settings.py 中的参数按自己的实际参数修改
# ########## AD配置修改为自己的# AD主机可以是IP或主机域名例如可以是: abc.com或172.16.122.1AD_HOST=r'修改成自己的'# AD域控的DOMAIN名例如abcAD_DOMAIN=r'修改成自己的'# 用于登录AD做用户信息处理的账号需要有修改用户账号密码或信息的权限。# AD账号例如pwdadminAD_LOGIN_USER=r'修改成自己的'# 密码AD_LOGIN_USER_PWD=r'修改为自己的'# BASE DN账号的查找DN路径例如'DC=abc,DC=com'可以指定到OU之下例如'OU=RD,DC=abc,DC=com'。BASE_DN=r'修改成自己的'# 是否启用SSL,# 注意AD必须使用SSL才能修改密码这里被坑了N久...,自行部署下AD的证书服务并颁发CA证书重启服务器生效。具体教程百度一下有很多。AD_USE_SSL=True# 连接的端口如果启用SSL默认是636否则就是389AD_CONN_PORT=636# 扫码验证的类型# 钉钉 / 企业微信自行修改# 值是DING / WEWORKSCAN_CODE_TYPE='DING'# ########## 钉钉 《如果不使用钉钉扫码可不用配置》########### 钉钉接口主地址不可修改DING_URL=r'https://oapi.dingtalk.com'# 钉钉企业ID <CorpId>修改为自己的DING_CORP_ID='修改为自己的'# 钉钉企业内部开发内部H5微应用或小程序用于读取企业内部用户信息DING_AGENT_ID=r'修改为自己的'DING_APP_KEY=r'修改为自己的'DING_APP_SECRET=r'修改为自己的'# 移动应用接入 主要为了实现通过扫码拿到用户的unionidDING_MO_APP_ID=r'修改为自己的'DING_MO_APP_SECRET=r'修改为自己的'# ####### 企业微信《如果不使用企业微信扫码可不用配置》 ########### 企业微信的企业IDWEWORK_CORP_ID=r'修改为自己的'# 应用的AgentIdWEWORK_AGENT_ID=r'修改为自己的'# 应用的SecretWEWORK_AGNET_SECRET=r'修改为自己的'# Redis配置# redis的连接地址redis://<Ip/Host>:<Port>/<数据库>REDIS_LOCATION=r'redis://127.0.0.1:6379/1'REDIS_PASSWORD=r'12345678'# ########################### 执行python3 ./utils/crypto.py 生成# 可自行生成后替换CRYPTO_KEY=b'dp8U9y7NAhCD3MoNwPzPBhBtTZ1uI_WWSdpNs6wUDgs='# COOKIE 超时单位是秒可不用修改TMPID_COOKIE_AGE=300# 主页域名钉钉跳转等需要指定域名格式pwd.abc.com。# 如果是自定义安装请修改成自己的域名HOME_URL='PWD_SELF_SERVICE_DOMAIN'
执行部署脚本
chmod +x auto-install.sh
./auto-install.sh
等待所有安装完成。
以上配置修改完成之后则可以通过配置的域名直接访问。
手动部署
自行安装完 python3 之后使用 python3 目录下的 pip3 进行安装依赖
我自行安装的 Python 路径为/usr/local/python3
项目目录下的 requestment 文件里记录了所依赖的相关 python 模块安装方法
/usr/local/python3/bin/pip3 install -r requestment
等待所有模块安装完成之后进行下一步。
按自己实际的配置修改项目配置参数
修改 conf/local_settings.py 中的参数按自己的实际参数修改
安装完依赖后直接执行 /usr/local/python3/bin/python3 manager.py runserver x.x.x.x:8000 即可临时访问项目线上不适用这种方法线上环境请使用 uwsgi。
# ########## AD配置修改为自己的
# AD主机可以是IP或主机域名例如可以是: abc.com或172.16.122.1
AD_HOST = r'修改成自己的'
# AD域控的DOMAIN名例如abc
AD_DOMAIN = r'修改成自己的'
# 用于登录AD做用户信息处理的账号需要有修改用户账号密码或信息的权限。
# AD账号例如pwdadmin
AD_LOGIN_USER = r'修改成自己的'
# 密码
AD_LOGIN_USER_PWD = r'修改为自己的'
# BASE DN账号的查找DN路径例如'DC=abc,DC=com'可以指定到OU之下例如'OU=RD,DC=abc,DC=com'。
BASE_DN = r'修改成自己的'
# 是否启用SSL,
# 注意AD必须使用SSL才能修改密码这里被坑了N久...,自行部署下AD的证书服务并颁发CA证书重启服务器生效。具体教程百度一下有很多。
AD_USE_SSL = True
# 连接的端口如果启用SSL默认是636否则就是389
AD_CONN_PORT = 636
# 扫码验证的类型
# 钉钉 / 企业微信自行修改
# 值是DING / WEWORK
SCAN_CODE_TYPE = 'DING'
# ########## 钉钉 《如果不使用钉钉扫码可不用配置》##########
# 钉钉接口主地址不可修改
DING_URL = r'https://oapi.dingtalk.com'
# 钉钉企业ID <CorpId>修改为自己的
DING_CORP_ID = '修改为自己的'
# 钉钉企业内部开发内部H5微应用或小程序用于读取企业内部用户信息
DING_AGENT_ID = r'修改为自己的'
DING_APP_KEY = r'修改为自己的'
DING_APP_SECRET = r'修改为自己的'
# 移动应用接入 主要为了实现通过扫码拿到用户的unionid
DING_MO_APP_ID = r'修改为自己的'
DING_MO_APP_SECRET = r'修改为自己的'
# ####### 企业微信《如果不使用企业微信扫码可不用配置》 ##########
# 企业微信的企业ID
WEWORK_CORP_ID = r'修改为自己的'
# 应用的AgentId
WEWORK_AGENT_ID = r'修改为自己的'
# 应用的Secret
WEWORK_AGNET_SECRET = r'修改为自己的'
# Redis配置
# redis的连接地址redis://<Ip/Host>:<Port>/<数据库>
REDIS_LOCATION = r'redis://127.0.0.1:6379/1'
REDIS_PASSWORD = r'12345678'
# ##########################
# 执行python3 ./utils/crypto.py 生成
# 可自行生成后替换
CRYPTO_KEY = b'dp8U9y7NAhCD3MoNwPzPBhBtTZ1uI_WWSdpNs6wUDgs='
# COOKIE 超时单位是秒可不用修改
TMPID_COOKIE_AGE = 300
# 主页域名钉钉跳转等需要指定域名格式pwd.abc.com。
# 如果是自定义安装请修改成自己的域名
HOME_URL = 'PWD_SELF_SERVICE_DOMAIN'
修改 uwsig.ini 配置:
IP 和路径按自己实际路径修改
[uwsgi]http-socket=PWD_SELF_SERVICE_IP:PWD_SELF_SERVICE_PORTchdir=PWD_SELF_SERVICE_HOMEmodule=pwdselfservice.wsgi:applicationmaster=trueprocesses=4threads=4max-requests=2000chmod-socket=755vacuum=true# 设置缓冲post-buffering=4096# 设置静态文件static-map=/static=PWD_SELF_SERVICE_HOME/static# 设置日志目录daemonize=PWD_SELF_SERVICE_HOME/log/uwsgi.log
通过 uwsgiserver 启动
其中 PWD_SELF_SERVICE_HOME 是你自己的服务器当前项目的目录请自行修改 将以下脚本修改完之后复制到/etc/init.d/给予执行权限。 uwsgiserver:
脚本内的路径按自己实际情况修改
自行部署 Nginx然后添加 Nginx 配置
[uwsgi]
http-socket = PWD_SELF_SERVICE_IP:PWD_SELF_SERVICE_PORT
chdir = PWD_SELF_SERVICE_HOME
module = pwdselfservice.wsgi:application
master = true
processes = 4
threads = 4
max-requests = 2000
chmod-socket = 755
vacuum = true
# 设置缓冲
post-buffering = 4096
# 设置静态文件
static-map = /static=PWD_SELF_SERVICE_HOME/static
# 设置日志目录
daemonize = PWD_SELF_SERVICE_HOME/log/uwsgi.log
# !/bin/sh
INI="PWD_SELF_SERVICE_HOME/uwsgi.ini"
UWSGI="/usr/share/python-3.6.9/bin/uwsgi"
PSID=`ps aux | grep "uwsgi"| grep -v "grep" | wc -l`
if [ ! -n "$1" ]
then
content="Usages: sh uwsgiserver [start|stop|restart]"
echo -e "\033[31m $content \033[0m"
exit 0
fi
if [ $1 = start ]
then
if [ `eval $PSID` -gt 4 ]
then
content="uwsgi is running!"
echo -e "\033[32m $content \033[0m"
exit 0
else
$UWSGI $INI
content="Start uwsgi service [OK]"
echo -e "\033[32m $content \033[0m"
fi
elif [ $1 = stop ];then
if [ `eval $PSID` -gt 4 ];then
killall -9 uwsgi
fi
content="Stop uwsgi service [OK]"
echo -e "\033[32m $content \033[0m"
elif [ $1 = restart ];then
if [ `eval $PSID` -gt 4 ];then
killall -9 uwsgi
fi
$UWSGI --ini $INI
content="Restart uwsgi service [OK]"
echo -e "\033[32m $content \033[0m"
else
content="Usages: sh uwsgiserver [start|stop|restart]"
echo -e "\033[31m $content \033[0m"
fi
Nginx 配置
Nginx Server 配置
proxy_pass 的 IP 地址改成自己的服务器 IP
配置可自己写一个 vhost 或直接加在 nginx.conf 中
执行 Nginx reload 操作重新加载配置
server {
listen 80;
server_name pwd.abc.com;
location / {
proxy_pass http://192.168.x.x:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
access_log off;
}
完整代码