通过企业微信自助重置 AD 域用户密码 2023/04/20 15:44 • 其他应用软件 • 阅读 10653 AD Password Self Service 是 @capricornxl 基于 Python + Django 创立的一个密码自助平台,用户通过钉钉或者企业微信授权,可以实现自助重置、解锁 AD 域用户密码。 项目地址:https://github.com/capricornxl/ad-password-self-service 目录 准备工作企业微信创建自建应用服务器系统基础配置配置密码自助平台搭建 Redis 服务配置 uwsgi 服务搭建 Nginx 服务应用上线测试 准备工作 本文的测试环境为 CentOS 7.8 操作系统,并且已搭建好 AD 域相关服务。另外你还需要一台带公网 IP 地址的服务器,以通过 API 接口获取企业微信数据。 如果配置过程中遇到项目文件无效,可尝试下载共享链接中的文件。(非必选) 百度网盘分享下载提取码:hmh1 阿里云盘分享下载提取码:au66 企业微信创建自建应用 1、使用企业微信管理员账号,点击此处 登录到管理后台。 2、选择「我的企业」>「企业信息」,在页面底部找到并记录下「企业 ID」。 3、接着选择「应用管理」>「应用」>「自建」,点击「创建应用」。 4、上传应用 Logo,并填写应用名称等信息,点击「创建应用」。 5、创建完成后进入应用,可以看到 AgentId、Secret 等信息,这些信息在使用企业微信 API 时会用到,选择「查看」Secret。 6、应用 Secret 会发送到管理员的消息列表中,请勿向第三方人员泄露密钥信息。 7、接着设置应用主页,应用类型选择「网页」,输入网页地址。 8、找到「开发者接口」下的「网页授权及 JS-SDK」,选择「设置可信域名」。 9、在「可信域名」下填写服务器的域名,并完成域名的归属认证。 10、接着设置「企业微信授权登录」,在「Web 网页」类型下设置「授权回调域」。 11、接着为应用配置一个「企业可信 IP」,输入服务器的公网 IP 地址。只有设置的服务器 IP 地址可以通过接口获取企业数据。 服务器系统基础配置 1、进入 CentOS 服务器,首先需要禁用 SELINUX 服务,输入以下命令编辑配置文件。 vi /etc/sysconfig/selinux 2、将 SELINUX=enforcing 指令更改为 SELINUX=disabled,保存退出。 3、修改成功后重启系统。 reboot 4、安装以下所需组件。 yum -y install wget yum -y install unzip yum -y install psmisc 5、CentOS 7.8 的默认 Python 版本为 2.7.5,需要将其升级到 3.8.2 版本。操作步骤可前往 https://blog.kobin.cn/blog/system/s2/2663.html 进行查看。 配置密码自助平台 1、将项目文件下载到服务器并解压。 cd /opt/ wget https://github.com/capricornxl/ad-password-self-service/archive/refs/heads/master.zip unzip master.zip # 这里我将文件夹重命名为对应的版本号,可根据实际情况进行调整 mv ad-password-self-service-master /opt/ad-password-self-service-1.0.6.1 2、使用 pip 安装依赖项,项目目录下的 requestment 文件里记录了所依赖的相关 Python 模块。 cd /opt/ad-password-self-service-1.0.6.1 pip install -r requirement 3、等待所有模块安装完成之后,修改配置文件 local_settings.py 的参数。 vi conf/local_settings.py 4、填写 AD 服务器的配置信息。 5、验证类型输入「WEWORK」,补充企业微信的「企业 ID」、「AgentId」和「Secret」信息。 6、填写「域名」和「站点标题」,并设置一个 Redis 服务的密码,完成后保存退出。 搭建 Redis 服务 参考文章:https://blog.csdn.net/qq_39187538/article/details/126485922 1、获取 Redis 安装包并解压。 cd /opt/ wget https://download.redis.io/releases/redis-7.0.2.tar.gz tar -zxvf redis-7.0.2.tar.gz 2、 进入解压后的 Redis 目录,使用 make 命令进行编译,并执行安装。 cd redis-7.0.2/ && make cd src/ && make install 3、安装完成后,编辑 redis.conf 配置文件。 vi /opt/redis-7.0.2/redis.conf 4、设置允许 Redis 服务在后台运行。 5、Redis 服务默认无密码,需要开启密码保护。此处设置的密码和 local_settings.py 中的密码保持一致。 6、设置允许访问 Redis 服务的 IP 地址。 7、配置文件修改完成后,保存退出。 8、在系统服务目录里创建 redis.service 文件。 vi /usr/lib/systemd/system/redis.service 9、在文件中添加以下内容,保存退出。 [Unit] Description=redis-server After=network.target [Service] Type=forking ExecStart=/usr/local/bin/redis-server /opt/redis-7.0.2/redis.conf PrivateTmp=true [Install] WantedBy=multi-user.target 10、重载系统服务,并启动 Redis 服务。 systemctl daemon-reload systemctl enable redis systemctl start redis 配置 uwsgi 服务 1、修改 uwsig.ini 配置文件。 vi /opt/ad-password-self-service-1.0.6.1/uwsgi.ini 2、设置项目目录的所在路径,以及线程数,完成后保存退出。 3、编辑 uwsgiserver 文件,设置项目目录的所在路径,以及 uwsgi 服务的所在路径,完成后保存退出。 vi /opt/ad-password-self-service-1.0.6.1/uwsgiserver # 查看 uwsgi 的安装位置 whereis uwsgi 4、将项目目录下的 uwsgiserver 复制到 /etc/init.d/,给予执行权限。 cp /opt/ad-password-self-service-1.0.6.1/uwsgiserver /etc/init.d/uwsgiserver chmod +x /etc/init.d/uwsgiserver 5、在系统服务目录里创建 uwsgiserver.service 文件。 vi /usr/lib/systemd/system/uwsgiserver.service 6、在文件中添加以下内容,保存退出。 [Unit] Description=uwsgiserver After=network.target [Service] Type=forking ExecStart=/etc/init.d/uwsgiserver start ExecReload=/etc/init.d/uwsgiserver restart ExecStop=/etc/init.d/uwsgiserver stop PrivateTmp=true [Install] WantedBy=multi-user.target 7、重载系统服务,并启动 uwsgiserver 服务。 systemctl daemon-reload systemctl enable uwsgiserver systemctl start uwsgiserver 搭建 Nginx 服务 参考文章:https://blog.csdn.net/qq_33381971/article/details/123328191 1、安装所需依赖项。 yum -y install gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel 2、获取 Nginx 安装包并解压。 cd /opt/ wget -c https://nginx.org/download/nginx-1.18.0.tar.gz tar -zxvf nginx-1.18.0.tar.gz 3、进入解压后的 Nginx 目录,执行安装。 cd nginx-1.18.0/ ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module make && make install 4、编辑 Nginx 配置文件,修改完成后保存退出。 vi /usr/local/nginx/conf/nginx.conf # 在 http 中添加以下命令 include vhosts/*.conf 5、创建虚拟主机文件夹和证书文件夹,并将 SSL 加密证书上传到该路径下。 mkdir -p /usr/local/nginx/conf/vhosts/cert/ad-password-self-service 6、创建虚拟主机配置文件。 vi /usr/local/nginx/conf/vhosts/ad-password-self-service.conf 7、添加以下内容后,保存退出。 server { listen 80; listen 443 ssl; server_name *****.com; # 此处输入站点域名 # 强制跳转HTTPS if ($server_port !~ 443){ rewrite ^(/.*)$ https://$host$1 permanent; } # 证书所在路径 ssl_certificate /usr/local/nginx/conf/vhosts/cert/ad-password-self-service/*****.pem; ssl_certificate_key /usr/local/nginx/conf/vhosts/cert/ad-password-self-service/*****.key; ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; ssl_session_timeout 10m; ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; ssl_prefer_server_ciphers on; location / { proxy_pass http://192.168.*.*:8443; # 此处输入公网 IP 地址和 uwsgi 服务端口 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; } 8、在系统服务目录里创建 nginx.service 文件。 vi /usr/lib/systemd/system/nginx.service 9、添加以下内容后,保存退出。 [Unit] Description=nginx service After=network.target [Service] Type=forking ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s quit PrivateTmp=true [Install] WantedBy=multi-user.target 10、重载系统服务,并启动 Nginx 服务。 systemctl daemon-reload systemctl enable nginx systemctl start nginx 应用上线测试 1、放行防火墙端口。 firewall-cmd --permanent --zone=public --add-port=80/tcp firewall-cmd --permanent --zone=public --add-port=443/tcp firewall-cmd --permanent --zone=public --add-port=8443/tcp firewall-cmd --reload 2、检查服务端口占用。 yum -y install net-tools netstat -tunlp 3、打开企业微信客户端,点击工作台,选择我们创建的应用。软件提示信息授权,点击同意。 4、成功进入应用页面,尝试进行密码重置操作。服务搭建完成。 本文为原创文章,著作权归作者所有:来自「KOBIN 技术随笔」作者的原创作品,转载请标明出处。通过企业微信自助重置 AD 域用户密码https://blog.kobin.cn/blog/program/p3/2671.html Active DirectoryCentOSLinuxPython企业微信 赞 (11) 0 38 生成海报 发表回复 您的电子邮箱地址不会被公开。 必填项已用 * 标注*昵称: *邮箱: 网址: 记住昵称、邮箱和网址,下次评论免输入 提交 CAPTCHAis initialing... 评论列表(38条) nico.li 2023/04/20 16:36 想部署私人chatgpt吗?可以参考我这篇教程https://tech.sharespace.top/myself-chatgpt-web/ 回复 apollo 2023/06/17 01:20 写得非常的不错,辛苦了。 回复 Gu 2023/07/13 01:06 想请问第6、域名填什么。 回复 KOBIN 2023/07/13 09:25 @Gu:用户访问前端网页时所用的域名 回复 Gu 2023/07/13 21:27 @KOBIN:LDAP_HOST = r”” 这里填内网的AD服务器嘛?外网请求不到吧 回复 KOBIN 2023/07/14 09:19 @Gu:这台服务器介于 AD 服务器和互联网之间,用户通过这台服务器的 Web 页面修改 AD 账户密码。所以说这台服务器需要和 AD 服务连通,同时还需要一个公网 IP 地址用于互联网上的用户进行访问。AD 服务器不用直接映射到公网上 回复 Gu 2023/07/17 18:46 @KOBIN:大佬求解,怎么让这台服务器介于AD互联之间… 这一步一直不知道怎么搞 回复 KOBIN 2023/07/17 23:04 @Gu:这台服务器需要和局域网连通,可以访问到 AD 服务器的 389 端口;同时需要为服务器分配一个公网 IP 地址,并将 80 和 443 端口映射到公网上。用户使用互联网访问到服务器的网页,验证授权后,通过这台服务器对 AD 账户密码进行修改。(简单点说,这台服务器要既可以访问内网,同时要给公网上的人访问)。 回复 Daniel 2024/05/10 10:53 @KOBIN:想请问下,这台服务器可以就用这台部署了修改密码项目的服务器么,还是说要单独用另外一台服务器?如果映射端口,公网的80和443端口默认不能使用的,需要备案,那么可以用公网的哪个端口代替? 还是说可以自己定义这个公网需要映射出去的端口? 回复 Joyable 2023/09/05 23:24 学习一下 回复 Daniel 2023/09/18 15:19 请问下,在nginx配置中,将 SSL 加密证书上传到该路径下,这个SSL证书是从哪里生成的,如何生成的? 回复 KOBIN 2023/09/18 15:44 @Daniel:可以用自签名 SSL 证书或者受信任的证书机构签发的 SSL 证书,前者是由自建的 CA 环境发布的,存在浏览器的安全信任问题,后者可以通过各家云厂商进行申请。HTTPS 不是强制的,但考虑到用户数据安全,建议还是部署 SSL 加密证书。 回复 Daniel 2023/09/18 17:07 @KOBIN:感谢,那么我在AD CA上如何生成这个自签名证书的 .pem 和 .key的证书文件了,有参考教程吗? 回复 KOBIN 2023/09/18 17:50 @Daniel:可以参考下这几篇文章,先搭建 AD CS 证书服务器 https://blog.kobin.cn/blog/system/s1/2032.html ,再申请一张自签证书 https://blog.kobin.cn/blog/system/s1/557.html ,最后把 pfx 证书转换下 https://blog.kobin.cn/blog/system/s1/555.html 回复 Daniel 2023/09/20 14:16 @KOBIN:非常感谢,按照自签证书的步骤https://blog.kobin.cn/blog/system/s1/557.html 生成的自签名证书是 .cer 格式,又该如何转换成 .pfx 格式了? 有相关教程指导下吗? 回复 KOBIN 2023/09/25 21:08 @Daniel:cer 文件不包含私钥信息。证书颁发成功后,可以在证书控制台里找到对应的证书文件,右击选择「导出」即可获取 pfx 文件,我博客里没有具体的操作说明,您可以参考下这篇文章 https://csmeta.emtholding.com/portal/en/kb/articles/how-to-replace-ca-signed-certificate-in-flexera-svm-virtal-appliance 回复 勿忘初心 2023/09/24 11:45 你好,看你的站做的挺不错的,有没有出手的打算,想出手的话,联系1587894193。 回复 General 2023/11/27 10:29 请教一下 我输入域工号(M000001) 修改密码时候提示 旧账号或则密码不正确(确认是正确的);是不是local_settings.py 关于SEARCH_FILTER = r'(&(objectclass=user)(sAMAccountName={0}))’ 这里的参数不对? 回复 KOBIN 2023/11/27 14:37 @General:源代码中是通过企业微信的邮箱地址,和 AD 域的用户名作关联匹配。也就是说企业微信中的员工绑定邮箱地址是 aaa@domain.com,那么 AD 域服务器中需要一个用户名为 aaa 的账户。默认不支持通过工号进行关联。 回复 冯天宇 2023/12/27 14:40 {% extends ‘base.html’ %} {% load static %} {% block headerjs %}{% endblock %} {% block paneltitle %}请稍后,授权信息认证中{% endblock %} {% block middleblock %} {% endblock %} {% block footerjs %} {% endblock %} 回复 聆听 2024/01/10 13:49 大佬我的重置密码的时候提示:获取userid失败,错误信息:get_user_ticket_by_code_with_oauth2: 40029-invalid code, hint: [1704865602101961140239199], from ip: 125.19.31.13, more info at https://open.work.weixin.qq.com/devtool/query?e=40029 回复 聆听 2024/01/10 14:06 大佬,我在企业微信里点重置密码提示:无法访问该网页,找不到访问网址的服务器IP地址 错误码: ERROR HOST LOOKUP 但是修改密码没有问题,在内网情况下在企业微信点重置密码正常。 回复 聆听 2024/01/10 17:09 大佬,我在企业微信里点重置密码提示:无法访问该网页,连接失败,错误码:ERROR_CONNECT 经过查询发现点“重置密码”的连接中少了一个s,本身网站是基于https:// 回复 镜科 2024/01/11 11:09 @聆听:我也遇到这个问题了,内网访问点重置密码可以打开,外部网络点重置密码少了个s,感觉nginx问题,nginx反项代理也做了80强制调转443 server{ listen 443 ssl; #对应你的域名 server_name test.ccnf.com; ssl_certificate /etc/nginx/cert/_.ccnf.com.cer; ssl_certificate_key /etc/nginx/cert/_.ccnf.com.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; #如果是静态文件,直接指向目录,如果是动态应用,用proxy_pass转发一下 location / { proxy_pass http://172.21.57.57:8443; } } #监听80端口,并重定向到443 server{ listen 80; server_name ccnf.founderpcb.com; rewrite ^/(.*)$ https:/test.ccnf.com:443/$1 permanent; } 回复 jt 2024/01/24 15:06 有没有单纯网页版的,不和企业微信钉钉集成的? 回复 niu 2024/03/11 16:17 我想问问,如果用户的企业微信是不是可以去修改别人的密码 回复 KOBIN 2024/03/11 16:36 @niu:目前的规则是通过企业微信用户绑定的邮箱地址前缀,来匹配对应的域账号,管理员可以在企业微信后台限制用户不允许自己修改邮箱地址,来规避这个问题,具体信息可以查看作者的说明文档 https://github.com/capricornxl/ad-password-self-service/blob/master/readme.md 回复 Daniel 2024/05/10 15:08 还有一个问题请教 9、在「可信域名」下填写服务器的域名,并完成域名的归属认证。这里的域名是指需要在外网申请一个域名么? 回复 KOBIN 2024/05/11 00:16 @Daniel:只需要一台服务器即可,这台服务器要求可以访问内网的 AD 控制器,同时需要一个公网 IP 地址,并将相应服务端口映射到外网供他人访问;另外向企业微信请求成员身份信息,需要注册一个域名,并且这个域名需要完成 ICP 备案,并且备案主体需要和企业微信认证的主体一致(这块我不太确定,你可以和企业微信的官方客服再核实下),相关流程参考 https://developer.work.weixin.qq.com/document/path/95672 回复 Daniel 2024/05/28 20:18 @KOBIN:感谢,再请问下,问题1:路由器端口映射,我是这样做的,将服务器的公网IP:8443 映射到内网服务器的私网IP:8443 ,其中8443是uwsgi 服务的端口,不知道是否正确,还是说要映射到内网的nginx服务器的端口80或者443? 问题2:我司有个域名,譬如是 abc.com , 我这边这个服务器的域名为 pwd.abc.com, 是不是还要在域名服务器上做一条A记录将这个 pwd.abc.com 域名指向这个服务器的公网IP? 然后通过外网用户通过访问这个域名pwd.abc.com ,由nginx跳转到内网的 IP:8443上,我的疑问是下面这个 proxy_pass这个 IP是不是应该写内网IP,而不是注释中的公网IP。非常感谢。 proxy_pass http://192.168.*.*:8443; # 此处输入公网 IP 地址和 uwsgi 服务端口 回复 Daniel 2024/06/24 10:46 @Daniel:已解决,针对第一问,将公网端口映射到内网的80或者443,然后通过proxy_pass代理到uwsgi 服务。 第二问,proxy_pass 地址是内网服务的地址 回复 超爱猪脚饭 2024/12/31 17:49 写的太好了,过年了,我想请你吃饭。猪脚饭。 回复 dd 2025/01/21 13:08 最终任意企业微信用户都能重置任意域用户的账号密码?可以做限制只能重置自己的密码吗? 回复 KOBIN 2025/01/22 09:11 @dd:重置前会有个用户授权的动作,你可以去 Github 项目看下,原作者有解释账号认证规则 回复 信 2025/01/23 16:30 请问这以下这些内容在哪个文件可以修改一下。谢谢! “新密码8至30位长度,要求包含大小写字母及数字。 如果密码己遗忘,可点击上方[ 重置/解锁账号]使用⌊微信⌉应用内免登录授权并通过身份验证后进行重置/解锁账号。 * 如果有当弹出提示是否同意授权时,请务必全部同意,否则无法获取关键信息,导致无法正常使用重置/解锁账号!” 回复 信 2025/01/24 10:16 @信:我改新密码10至30位长度 回复 William 2025/02/12 11:07 请问这个部署完成后不能直接在本地浏览器访问进行测试验证?必须映射公网通过企业微信去访问对? 回复 yihaung 2025/02/17 15:00 请问一下可信域名我都配置好了,有个报错禁止访问(403),CSRF验证失败,请求被中断 回复