当前位置: 首页 > article >正文

Hyperf方案 LDAP/AD 企业登录集成

用 directorytree/ldaprecord 最好下面完整实现tive Directory2025)---核心思路 · ↓196tokens)用户输入账号密码 ↓ 去公司 AD/LDAP 服务器验证不是你自己的数据库 ↓ 验证通过 → 拉取用户信息姓名、邮箱、部门、角色组 ↓ 生成 JWT Token 返回给前端 ↓ 后续请求带 Token正常鉴权---安装 composer require directorytree/ldaprecord hyperf/jwt-auth---目录结构 app/Controller/AuthController.php # 登录接口 Service/LdapService.php # LDAP核心逻辑 Middleware/JwtMiddleware.php # Token验证 config/autoload/ldap.php # LDAP配置---1.配置// config/autoload/ldap.phpreturn[default[hosts[env(LDAP_HOST,192.168.1.10)],portenv(LDAP_PORT,389),base_dnenv(LDAP_BASE_DN,DCcompany,DCcom),// 用一个只读服务账号去查询不能用普通用户usernameenv(LDAP_USERNAME,CNldap-reader,OUServiceAccounts,DCcompany,DCcom),passwordenv(LDAP_PASSWORD,service-account-password),use_sslenv(LDAP_SSL,false),// 生产环境建议开启 LDAPSuse_tlsenv(LDAP_TLS,false),],];LDAP_HOST192.168.1.10LDAP_BASE_DNDCcompany,DCcom LDAP_USERNAMECNldap-reader,OUServiceAccounts,DCcompany,DCcom LDAP_PASSWORDyour-service-password---2.LDAP 服务核心// app/Service/LdapService.php?php namespace App\Service;use LdapRecord\Connection;use LdapRecord\Auth\BindException;classLdapService{private Connection $conn;private array $config;publicfunction__construct(){$this-configconfig(ldap.default);$this-connnewConnection($this-config);$this-conn-connect();}/** * 登录验证 * 流程先用服务账号查到用户的完整DN再用用户自己的密码去绑定验证 */publicfunctionlogin(string $username,string $password):?array{// 第一步用服务账号查找这个用户因为直接绑定需要完整DN用户不知道自己的DN$user$this-findUser($username);if(!$user){returnnull;// 用户不存在}// 第二步用用户自己的密码验证绑定到LDAPtry{$this-conn-auth()-attempt($user[dn],$password,$bindAsUsertrue);}catch(BindException){returnnull;// 密码错误}return$user;}/** * 查找用户返回用户信息 */publicfunctionfindUser(string $username):?array{// sAMAccountName 是 AD 里的登录名就是你平时登录Windows用的那个$result$this-conn-query()-where(sAMAccountName,,$username)-whereEnabled()// 只查启用的账号-first();if(!$result){returnnull;}return[dn$result[dn],username$this-attr($result,samaccountname),name$this-attr($result,displayname)?:$this-attr($result,cn),email$this-attr($result,mail),department$this-attr($result,department),title$this-attr($result,title),// 职位phone$this-attr($result,telephonenumber),groups$this-getUserGroups($result),// 所属AD组];}/** * 获取用户所属的AD安全组用来做权限控制 */privatefunctiongetUserGroups(array $entry):array{if(empty($entry[memberof])){return[];}$groupsis_array($entry[memberof])?$entry[memberof]:[$entry[memberof]];// 从 CNIT部门,OUGroups,DCcompany,DCcom 里提取 IT部门returnarray_map(function($dn){preg_match(/^CN([^,])/i,$dn,$matches);return$matches[1]??$dn;},$groups);}// LDAP返回的属性值是数组取第一个privatefunctionattr(array $entry,string $key):string{$val$entry[$key]??;returnis_array($val)?($val[0]??):$val;}}---3.登录控制器// app/Controller/AuthController.php?php namespace App\Controller;use App\Service\LdapService;use Hyperf\Di\Annotation\Inject;use Hyperf\HttpServer\Annotation\Controller;use Hyperf\HttpServer\Annotation\PostMapping;use Hyperf\HttpServer\Contract\RequestInterface;use Hyperf\HttpServer\Contract\ResponseInterface;use Phper666\JWTAuth\JWT;#[Controller(prefix:/auth)]classAuthController{#[Inject]private LdapService $ldap;#[Inject]private JWT $jwt;#[PostMapping(path:/login)]publicfunctionlogin(RequestInterface $request,ResponseInterface $response){$username$request-input(username);$password$request-input(password);if(!$username||!$password){return$response-json([code400,msg账号密码不能为空]);}$user$this-ldap-login($username,$password);if(!$user){return$response-json([code401,msg账号或密码错误]);}// 生成 JWT把用户信息存进去$token$this-jwt-getToken(default,[username$user[username],name$user[name],email$user[email],department$user[department],groups$user[groups],]);return$response-json([code200,msg登录成功,data[token$token-toString(),userinfo$user,],]);}#[PostMapping(path:/logout)]publicfunctionlogout(ResponseInterface $response){$this-jwt-logout();return$response-json([code200,msg已退出]);}}---4.权限中间件按AD组控制权限// app/Middleware/LdapGroupMiddleware.php?php namespace App\Middleware;use Phper666\JWTAuth\JWT;use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use Psr\Http\Server\MiddlewareInterface;use Psr\Http\Server\RequestHandlerInterface;classLdapGroupMiddlewareimplementsMiddlewareInterface{publicfunction__construct(private JWT $jwt){}publicfunctionprocess(ServerRequestInterface $request,RequestHandlerInterface $handler):ResponseInterface{$payload$this-jwt-getParserData();$groups$payload[groups]??[];// 把用户的AD组信息注入请求后续控制器可以直接用$request$request-withAttribute(user,$payload)-withAttribute(groups,$groups);return$handler-handle($request);}}// 在控制器里检查权限publicfunctionadminAction(RequestInterface $request){$groups$request-getAttribute(groups,[]);if(!in_array(IT管理员,$groups)){return[code403,msg无权限];}// 业务逻辑...}---5.路由配置// config/routes.phpRouter::post(/auth/login,[AuthController::class,login]);// 需要登录的接口加 JWT 中间件Router::addGroup(/api,function(){Router::get(/profile,[UserController::class,profile]);Router::get(/admin,[AdminController::class,index]);},[middleware[\Phper666\JWTAuth\Middleware\JWTAuthMiddleware::class,LdapGroupMiddleware::class]]);---整体流程图 前端 POST/auth/login{username,password}↓ LdapService::login()↓ 用服务账号 查 AD 找到用户DN ──→ 用户不存在 → 返回401↓ 找到了 用用户密码绑定验证 ──→ 密码错误 → 返回401↓ 验证通过 拉取姓名/邮箱/部门/AD组 ↓ 生成JWT Token ↓ 返回Token给前端 后续请求带Token → 中间件解析 → 注入用户信息 → 控制器按AD组判断权限---常见 AD 属性对照 ┌─────────────────┬───────────────────────┐ │ 属性 │ 含义 │ ├─────────────────┼───────────────────────┤ │ sAMAccountName │ 登录名如 zhangsan │ ├─────────────────┼───────────────────────┤ │ displayName │ 显示名如 张三 │ ├─────────────────┼───────────────────────┤ │ mail │ 邮箱 │ ├─────────────────┼───────────────────────┤ │ department │ 部门 │ ├─────────────────┼───────────────────────┤ │ title │ 职位 │ ├─────────────────┼───────────────────────┤ │ memberOf │ 所属安全组 │ ├─────────────────┼───────────────────────┤ │ telephoneNumber │ 电话 │ └─────────────────┴───────────────────────┘ 生产环境记得开 use_ssltrue用 LDAPS端口636明文传密码不安全。

相关文章:

Hyperf方案 LDAP/AD 企业登录集成

用 directorytree/ldaprecord 最好,下面完整实现:tive Directory 2025")---核心思路 ↓ 196 tokens)用户输入…...

别再让报表卡死了!手把手教你用PowerBI性能分析器揪出慢查询元凶

别再让报表卡死了!手把手教你用PowerBI性能分析器揪出慢查询元凶 每次打开报表都要等上几分钟?筛选器一拖就卡死?作为资深PowerBI用户,我完全理解这种痛苦。上周刚帮一家零售企业解决了他们的月度销售报表问题——原本需要3分钟加…...

如何高效获取B站视频的15维数据?Bilivideoinfo一站式解决方案

如何高效获取B站视频的15维数据?Bilivideoinfo一站式解决方案 【免费下载链接】Bilivideoinfo Bilibili视频数据爬虫 精确爬取完整的b站视频数据,包括标题、up主、up主id、精确播放数、历史累计弹幕数、点赞数、投硬币枚数、收藏人数、转发人数、发布时间…...

从C++源码到Python调用:手把手教你用CMake和ctypes打包一个跨平台可用的DLL

从C源码到Python调用:构建跨平台DLL的工程化实践 当我们需要将高性能的C模块暴露给Python调用时,动态链接库(DLL/SO)是最常见的桥梁。但许多开发者往往在最后一步——Python调用环节才意识到问题,此时调试成本已大幅增…...

从洛谷P1996约瑟夫问题实战出发:手把手调试C语言循环链表,解决内存泄漏与指针越界

从洛谷P1996约瑟夫问题实战出发:手把手调试C语言循环链表,解决内存泄漏与指针越界 约瑟夫环问题作为数据结构与算法中的经典案例,常被用来考察程序员对循环链表和指针操作的掌握程度。但真正在工程实践中实现一个健壮的约瑟夫环解决方案&…...

别再一帧帧看视频了!用MS-TCN++搞定厨房早餐动作自动分割(附Breakfast数据集实战)

用MS-TCN实现厨房早餐视频的智能动作分割:从数据准备到模型部署全流程 清晨的厨房里,煎蛋的滋滋声、面包机的弹出声、咖啡机的蒸汽声交织在一起——这些看似简单的早餐准备动作,在计算机视觉领域却蕴含着复杂的时序模式识别问题。传统逐帧标注…...

OpenLayers实战:5分钟搞定天地图WMTS与XYZ加载(附完整代码)

OpenLayers实战:5分钟搞定天地图WMTS与XYZ加载(附完整代码) 第一次接触天地图服务时,我被它丰富的图层类型和稳定的服务所吸引,但在集成过程中却踩了不少坑。作为国内最权威的在线地图服务之一,天地图同时支…...

GHelper完整指南:3分钟掌握华硕笔记本轻量控制工具,彻底告别臃肿系统

GHelper完整指南:3分钟掌握华硕笔记本轻量控制工具,彻底告别臃肿系统 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephy…...

Kubernetes的iptables 与 IPVS【20260419004篇】

文章目录 Kubernetes网络全景解析:内网/外网流量、CNI与Ingress深度指南 第一部分:Kubernetes网络流量模型 1.1 内网流量与外网流量的本质区别 1.1.1 流量类型定义与特征 1.1.2 流量路径对比 1.2 Kubernetes网络模型四大基础原则 第二部分:CNI插件深度解析 2.1 Flannel:简单…...

AIVideo问题解决:常见报错处理与参数调优,让视频生成更稳定

AIVideo问题解决:常见报错处理与参数调优,让视频生成更稳定 1. 常见报错分析与解决方案 1.1 部署阶段报错处理 报错1:环境变量配置无效 当修改.env文件后视频生成仍失败时,通常是因为配置未生效。正确的处理流程应该是&#x…...

告别时间不准!用Arduino Nano和DS3231模块DIY一个高精度数字时钟(附完整代码)

用Arduino Nano和DS3231打造高精度数字时钟的完整指南 你是否厌倦了手机和电脑上那些时不时需要手动校准的时间显示?市面上大多数电子时钟要么走时不准,要么功能单一。今天,我们将用Arduino Nano和DS3231实时时钟模块,打造一个走时…...

离线环境也能玩转ROS Gazebo:离线部署完整模型库(含sun/ground_plane)的完整指南

离线环境下的ROS Gazebo模型库全攻略:从部署到实战 在机器人开发与教学领域,Gazebo作为一款高保真物理仿真工具,其重要性不言而喻。然而,许多开发者都曾遇到过这样的困境:当网络连接不稳定或完全离线时,Gaz…...

AJ-Captcha:多端行为验证码技术架构与安全防护工程实践

AJ-Captcha:多端行为验证码技术架构与安全防护工程实践 【免费下载链接】captcha 行为验证码(滑动拼图、点选文字),前后端(java)交互,包含h5/Android/IOS/flutter/uni-app的源码和实现 项目地址: https://gitcode.com/gh_mirrors/captc/cap…...

如何让IDM告别试用期限制?3种实用方案全面解析

如何让IDM告别试用期限制?3种实用方案全面解析 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Reset Script 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script 你是否曾经因为Internet Download Manager&#xff08…...

浏览器界面革命:垂直标签如何重塑现代网页浏览体验

浏览器界面革命:垂直标签如何重塑现代网页浏览体验 【免费下载链接】vertical-tabs-chrome-extension A chrome extension that presents your tabs vertically. Problem solved. 项目地址: https://gitcode.com/gh_mirrors/ve/vertical-tabs-chrome-extension …...

高效网站本地化:WebSite-Downloader完整实战指南

高效网站本地化:WebSite-Downloader完整实战指南 【免费下载链接】WebSite-Downloader 项目地址: https://gitcode.com/gh_mirrors/web/WebSite-Downloader 想要永久保存重要的网站内容吗?WebSite-Downloader网站下载器让你轻松实现网站离线浏览…...

淘宝淘金币自动化脚本:5分钟完成每日任务的终极解决方案

淘宝淘金币自动化脚本:5分钟完成每日任务的终极解决方案 【免费下载链接】taojinbi 淘宝淘金币自动执行脚本,包含蚂蚁森林收取能量,芭芭农场全任务,解放你的双手 项目地址: https://gitcode.com/gh_mirrors/ta/taojinbi 每…...

一键下载30+文档平台:kill-doc让你轻松保存网页内容

一键下载30文档平台:kill-doc让你轻松保存网页内容 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为了解决…...

告别Keil MDK5!用VSCode+PlatformIO搭建LVGL开发环境(STM32篇)

用VSCodePlatformIO打造现代化LVGL开发环境(STM32实战指南) 嵌入式开发领域正在经历一场工具链革命——传统笨重的IDE逐渐被轻量化编辑器智能插件的组合取代。如果你还在用Keil MDK5进行STM32上的LVGL开发,不妨试试这套VSCodePlatformIO方案&…...

天赐范式第16天:【硬核反骨】哥本哈根沉默:REM睡眠是大脑在50维相空间的“超决定论”搜索(附Python源码)

摘要:梦境不是随机的噪声,而是意识在混沌边缘的精确计算。本文基于 Kuramoto 高维耦合振子模型,利用纯 Python (NumPy) 模拟了快速动眼期(REM)的神经动力学。实验发现:系统在 李雅普诺夫指数 λ0.0086 的弱…...

Genshin Impact API 深度解析与实战指南

Genshin Impact API 深度解析与实战指南 【免费下载链接】api A fan-made Genshin Impact API for easy access to game data. 项目地址: https://gitcode.com/gh_mirrors/api13/api GenshinDev API 是一个专门为《原神》游戏数据提供结构化访问接口的开源项目。通过提供…...

F3D三维查看器:技术专家视角下的高性能3D渲染解决方案

F3D三维查看器:技术专家视角下的高性能3D渲染解决方案 【免费下载链接】f3d Fast and minimalist 3D viewer. 项目地址: https://gitcode.com/GitHub_Trending/f3/f3d F3D是一个专注于性能和简洁性的开源三维查看器,为开发者和技术用户提供极致的…...

从源码到实战:深度定制你的Stable-Baselines3 Actor-Critic网络(含共享层设计)

从源码到实战:深度定制你的Stable-Baselines3 Actor-Critic网络(含共享层设计) 在强化学习领域,Actor-Critic架构因其结合了策略梯度与值函数估计的双重优势,已成为解决复杂决策问题的首选方案。而Stable-Baselines3作…...

从AMR到EVS:VoLTE/VoNR通话质量升级背后,RTP打包格式到底变了啥?(附新旧协议对比表)

从AMR到EVS:VoLTE/VoNR通话质量升级背后的RTP打包格式演进 1. 语音编解码技术的代际跃迁 2000年代初期的AMR-NB(Adaptive Multi-Rate Narrowband)编解码器定义了12.2kbps至4.75kbps的可变比特率,采样率固定在8kHz,频…...

华硕笔记本性能控制黑科技深度体验报告:轻量级控制工具的完全解放秘籍

华硕笔记本性能控制黑科技深度体验报告:轻量级控制工具的完全解放秘籍 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow,…...

Zynq7000双核实战:手把手教你用VxWorks6.9和WorkBench3.3实现任务绑定CPU

Zynq7000双核实战:手把手教你用VxWorks6.9和WorkBench3.3实现任务绑定CPU 当你第一次拿到ZedBoard开发板时,可能会被它强大的双核Cortex-A9架构吸引,但随之而来的问题是:如何充分利用这两个核心?在嵌入式开发中&#x…...

IDR深度解析:Delphi逆向工程的终极实战指南

IDR深度解析:Delphi逆向工程的终极实战指南 【免费下载链接】IDR Interactive Delphi Reconstructor 项目地址: https://gitcode.com/gh_mirrors/id/IDR 当你面对一个没有源代码的Delphi程序,需要分析其内部逻辑、恢复丢失的代码或进行安全审计时…...

告别‘一视同仁’:Focal Sparse Conv如何让3D检测网络学会‘看重点’(附KITTI实战)

告别“一视同仁”:Focal Sparse Conv如何让3D检测网络学会“看重点” 在自动驾驶和机器人领域,3D物体检测一直是核心技术难题之一。激光雷达扫描得到的点云数据天然具有稀疏性和不均匀性——前景物体(如车辆、行人)的体素往往比背…...

3个步骤彻底释放惠普OMEN游戏本隐藏性能:告别官方软件束缚

3个步骤彻底释放惠普OMEN游戏本隐藏性能:告别官方软件束缚 【免费下载链接】OmenSuperHub 使用 WMI BIOS控制性能和风扇速度,自动解除DB功耗限制。 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否曾经对着自己昂贵的惠普OMEN游…...

PyAnnote Audio技术深度解析:构建企业级说话人识别系统的全面指南

PyAnnote Audio技术深度解析:构建企业级说话人识别系统的全面指南 【免费下载链接】pyannote-audio Neural building blocks for speaker diarization: speech activity detection, speaker change detection, overlapped speech detection, speaker embedding 项…...