dotNET Core 中怎样操作 AD?

640?wx_fmt=jpeg

做企业应用开发难免会跟 AD 打交道,在之前的 dotNET FrameWork 时代,通常使用 System.DirectoryServices 的相关类来操作 AD ,在 dotNET Core 中没有这个命名空间,在张善友大佬的推荐下,知道了 Novell.Directory.Ldap。

操作 AD,通常有两种常见的场景:

  • 将第三方数据源数据(人事系统)同步到 AD 中

  • 将 AD 数据同步到自己的数据库中

本文将介绍在 dotNET Core 中使用 Novell.Directory.Ldap 将 AD 数据同步到数据库的操作。

环境

  • dotNET Core:2.1

  • Novell.Directory.Ldap.NETStandard2_0:3.1.0

安装 Novell.Directory.Ldap 包

在 VS2019 中添加 NuGet 包引用,如下图:

640?wx_fmt=png

安装完成后,在类中添加using Novell.Directory.Ldap;引用便可使用相关的 API 方法了。

同步思路

1、连接 AD

基本操作

同步方法

public bool Sync()
{ADConnect();if (_connection == null){throw new Exception("AD连接错误,请确认AD相关信息配置正确!");}bool result = true;List<LdapEntry> entryList = this.GetRootEntries(_adPaths, _adHost);_org = new Org();_user = new User();Org rootOrg = _org.GetRootOrg();foreach (LdapEntry entry in entryList){SyncDirectoryEntry(entry, rootOrg, entry);}return result;
}

连接 AD

public bool ADConnect()
{_adHost = "192.168.16.160";string adAdminUserName = "administrator";string adAdminPassword = "123456";_adPaths =new string[] { "OU=oec2003,DC=COM,DC=cn" };if ((string.IsNullOrEmpty(_adHost) || string.IsNullOrEmpty(adAdminUserName)) ||string.IsNullOrEmpty(adAdminPassword)){return false;}try{_connection = new LdapConnection();_connection.Connect(_adHost, LdapConnection.DEFAULT_PORT);_connection.Bind(adAdminUserName, adAdminPassword);}catch{return false;}return true;
}

递归操作

private void SyncDirectoryEntry(LdapEntry rootEntry, Org parentOrg, LdapEntry currentEntry)
{List<LdapEntry> entryList = currentEntry.Children(_connection);foreach (LdapEntry entry in entryList){if (entry.IsOrganizationalUnit()){Org org = this.SyncOrgFromEntry(rootEntry, parentOrg, entry);this.SyncDirectoryEntry(rootEntry, org, entry);}else if (entry.IsUser()){this.SyncUserFromEntry(rootEntry, parentOrg, entry);}}
}

同步部门

private Org SyncOrgFromEntry(LdapEntry rootEntry, Org parentOrg, LdapEntry entry)
{string orgId = entry.Guid().ToLower();Org org = this._org.GetOrgById(orgId) as Org;if (org != null){if (entry.ContainsAttr("ou")){org.Name = entry.getAttribute("ou").StringValue + string.Empty;}//设置其他属性的值_org.UpdateOrg(org);return org;}org = new Org{Id = orgId,ParentId = parentOrg.Id,};//设置其他属性的值this._org.AddOrg(org);return org;
}

同步用户

private User SyncUserFromEntry(LdapEntry rootEntry, Org parentOrg, LdapEntry entry)
{string userId = entry.Guid().ToLower();User user = this._user.GetUserById(userId);if (user != null){user.ParentId = parentOrg.Id;//设置其他属性的值this._user.UpdateUser(user);return user;}user = new User{Id = userId,ParentId = parentOrg.Id};//设置其他属性的值this._user.AddUser(user);return user;
}

辅助方法

为了方便代码的编写和复用,将一些操作提取到了扩展方法中。

获取 Entry 的 GUID

public static string Guid(this LdapEntry entry)
{var bytes = (byte[])(entry.getAttribute("objectGUID").ByteValue as object);var guid = new Guid(bytes);return guid.ToString();
}

获取 Entry 的 子级

public static List<LdapEntry> Children(this LdapEntry entry, LdapConnection connection)
{//string filter = "(&(objectclass=user))";List<LdapEntry> entryList = new List<LdapEntry>();LdapSearchResults lsc = connection.Search(entry.DN, LdapConnection.SCOPE_ONE, "objectClass=*", null, false);if (lsc == null) return entryList;while (lsc.HasMore()){LdapEntry nextEntry = null;try{nextEntry = lsc.Next();if (nextEntry.IsUser() || nextEntry.IsOrganizationalUnit()){entryList.Add(nextEntry);}}catch (LdapException e){continue;}}return entryList;
}

判断 Entry 是否为用户

public static bool IsUser(this LdapEntry entry)
{return entry.ObjectClass().Contains("user");
}

判断 Entry 是否为部门

public static bool IsOrganizationalUnit(this LdapEntry entry)
{return entry.ObjectClass().Contains("organizationalunit");
}

获取 Entry 的修改时间

public static DateTime WhenChanged(this LdapEntry entry)
{string value = entry.getAttribute("whenChanged").StringValue;if (value.Split('.').Length > 1){value = value.Split('.')[0];}DateTime whenChanged = DateTime.ParseExact(value, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);return whenChanged;
}

判断 Entry 中属性是否存在

public static bool ContainsAttr(this LdapEntry entry, string attrName)
{LdapAttribute ldapAttribute = new LdapAttribute(attrName);return entry.getAttributeSet().Contains(ldapAttribute);
}

根据名称获取 Entry 中的属性值

public static string AttrStringValue(this LdapEntry entry, string attrName)
{if (!entry.ContainsAttr(attrName)){return string.Empty;}return entry.getAttribute(attrName).StringValue;
}

总结

文中没有做更多文字性的介绍,可以从下面链接中下载代码进行调试就很容易理解了。

参考

示例代码:https://github.com/oec2003/StudySamples/tree/master/DotNetCoreAdDemo/DotNetCoreAdDemo

祝大家国庆假期快乐!

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313571.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

操作系统——页面置换算法

一、页面置换算法简介 操作系统将内存按照页的进行管理&#xff0c;在需要的时候才把进程相应的部分调入内存。当产生缺页中断时&#xff0c;需要选择一个页面写入。如果要换出的页面在内存中被修改过&#xff0c;变成了“脏”页面&#xff0c;那就需要先写会到磁盘。页面置换…

在树莓派4上安装 .NET Core 3.0 运行时及 SDK

点击上方蓝字关注“汪宇杰博客”导语我最近买了个树莓派4&#xff0c;4GB内存高富帅配置&#xff0c;并安装了官方操作系统Raspbian。今天我成功运行了一个ASP.NET Core 3.0 应用程序。我们来看看怎么弄的吧~ARM32 还是 ARM64?需要说明的是&#xff0c;目前无法在树莓派 4 上运…

.NET生成漂亮桌面背景

前言一天&#xff0c;我朋友指着某某付费软件对我说&#xff0c;这个东西不错&#xff0c;每天生成一张桌面背景&#xff0c;还能学英语&#xff08;放置名人名言和翻译&#xff09;&#xff01;我说&#xff0c;这东西搞不好我也能做&#xff0c;然后朋友说&#xff0c;“如果…

Mysql 执行流程

mysql执行一个查询的过程&#xff0c;到底做了些什么&#xff1a; 客户端发送一条查询给服务器&#xff1b;服务器先检查查询缓存&#xff0c;如果命中了缓存&#xff0c;则立刻返回存储在缓存中的结果。否则进入下一阶段。服务器段进行SQL解析、预处理&#xff0c;在优化器生成…

Autofac的AOP面向切面编程研究

我的理解是 把系统性的编程工作封装起来 》我给这个取个名字叫 “Aspect”&#xff0c;然后通过AOP技术把它切进我们的业务逻辑代码 》 “业务“这样的好处&#xff1a;“Aspect” 和 “业务” 相互独立&#xff0c;既可以让“业务” 用到了 “Aspect” 又让2者互相独立不耦合&…

计算机网络原理梳理丨清晰认识 TCP/IP 协议,图解秒懂!

作者&#xff1a;MobMsg&#xff0c;资深全端工程师一枚&#xff0c;架构师社区合伙人&#xff01;TCP/IP 协议族Internet 的核心协议就是 TCP/IP&#xff0c;广泛应用于局域网和广域网&#xff0c;目前已有20年发展史&#xff0c;是现用国际通行标准。TCP/IP 是个协议族&#…

MySQL 覆盖索引、最左前缀原则、索引下推

1、覆盖索引 1.1 概念 索引是高效找到行的一个方法&#xff0c;当能通过检索索引就可以读取想要的数据&#xff0c;那就不需要再到数据表中读取行了。如果一个索引包含了&#xff08;或覆盖了&#xff09;满足查询语句中字段与条件的数据就叫做覆盖索引。 1.2 判断标准 使用…

Entity Framework Core生成的存储过程在MySQL中需要进行处理及PMC中的常用命令

在使用Entity Framework Core生成MySQL数据库脚本&#xff0c;对于生成的存储过程&#xff0c;在执行的过程中出现错误&#xff0c;需要在存储过程前面添加delimiter //附&#xff1a;可以使用Visual Studio中的程序包管理器控制台执行Entity Framework Core中的迁移命令。PMC …

Exceptionless 5.0.0本地Docker快速部署介绍

在之前我有专门写两篇文章介绍过Exceptionless这款开源日志项目的使用和部署&#xff0c;但是当时是基于4.1.0版本&#xff08;2017年的release&#xff09;&#xff0c;时隔两年多Exceptionless也推出了5.0.0版本。&#xff08;1&#xff09;&#xff08;2&#xff09;01—关于…

数据库事务及隔离级别

一、事务的基本要素&#xff08;ACID&#xff09; 1、原子性&#xff08;Atomicity&#xff09;&#xff1a;事务开始后所有操作&#xff0c;要么全部做完&#xff0c;要么全部不做&#xff0c;不可能停滞在中间环节。事务执行过程中出错&#xff0c;会回滚到事务开始前的状态…

定了!10 月 8 日!Jupyter Notebook 原生支持将正式来到 VS Code!

北京时间 2019 年 9 月 21 日&#xff0c;在 PyCon China 2019 大会上&#xff0c;前不久&#xff0c;我们已经可以尽管如此&#xff0c;还是有许多童鞋来询问这个功能何时能正式发布。现在&#xff0c;我们可以在 VS Code Python 插件的 Release Plan 看到正式的发布时间已经确…

图解MySQL 内连接、左连接、右连接

一、准备工作 用两个表&#xff08;a_table、b_table&#xff09;&#xff0c;关联字段a_table.a_id和b_table.b_id来演示一下MySQL的内连接、外连接&#xff08; 左(外)连接、右(外)连接、全(外)连接&#xff09;。 MySQL版本&#xff1a;Server version: 5.6.31 MySQL Comm…

微软想将新版Edge浏览器引入Linux

继推出 WSL2、将 exFAT 技术添加至 Linux 内核&#xff0c;和宣布第一届微软 Linux 大会后&#xff0c;微软再次瞄准了 Linux。这次 Linux 用户将很可能迎来新版 Edge 浏览器。微软网络技术程序经理 Sean Larson 在 Twitter 上发布了一条消息&#xff0c;表示 Edge 开发团队正在…

一套代码同时支持.NET Framework和.NET Core

在.NET Core的迁移过程中&#xff0c;我们将原有的.NET Framework代码迁移到.NET Core。如果线上只有一个小型的应用还好&#xff0c;迁移升级完成后&#xff0c;只需要维护.NET Core这个版本的代码。但是&#xff0c;如果是一个大型分布式应用&#xff0c;几百台Server&#x…

从壹开始 [Admin] 之五 ║ 实现『按钮』级别权限配置

正文一、前情回顾哈喽大家好&#xff0c;在这个欢庆的日子里&#xff0c;老张祝大家工作都能蒸蒸日上&#xff01;今天正好也是社团成立的第一天&#xff0c;我也是希望今天能是个纪念日&#xff0c;沾沾这个大喜庆&#xff01;放假这两天&#xff0c;倒是学到了很多东西&#…

MySQL——binlog,redo log

一、什么是binlog、redo log binlog属于逻辑日志&#xff0c;是逻辑操作。innodb redo属于物理日志&#xff0c;是物理变更。逻辑日志有个缺点是难以并行&#xff0c;而物理日志可以比较好的并行操作。 binlog是MySQL Server层记录的日志&#xff0c; redo log是InnoDB存储引…

“自启动”树莓派上的 .NET Core 3.0 环境

点击上方蓝字关注“汪宇杰博客”导语昨天发了一篇《自动配置环境变量Rapbian 系统启动时会去执行 .profile 文件里的命令。因此我们只需要把配置环境变量的命令加入 .profile 文件即可。在 Linux 中&#xff0c;.profile 扩展用于终端程序中的文件。Linux 和 Mac OS X 终端程序…

Nginx 配置内网访问树莓派4 ASP.NET Core 3.0 网站

喜迎国庆点击上方蓝字关注“汪宇杰博客”导语前几天发了两篇《能跑就行&#xff1a;Kestrel Hosting如果你的要求只是临时内网访问&#xff0c;可以只用 Kestrel 来承载 Web 服务器&#xff0c;只需要给 dotnet 命令一个 --urls 参数即可设置允许访问的主机名和端口号。我不希望…

常见的NoSQL数据库

NoSQL数据库发展迅猛&#xff0c;据说现在已经有上百种NoSQL数据库了&#xff0c;下面来了解下常见的一些NoSQL数据库 先来看张表&#xff0c;了解下典型的NoSQL数据库的分类 NoSQL一般特征&#xff1a; 临时性键值存储一般作为关系型数据库的缓存来使用由于存在数据丢失的可…

2019年9月中国编程语言排行榜,C#排第三

前两天&#xff0c;在 GitHub 上看到一份报告&#xff0c;上面统计了全国程编程语言排行榜 9 月份的情况&#xff0c;下面跟大家分享一下&#xff0c;这份报告里面都说了什么。https://github.com/juwikuang/china_job_survey/blob/master/notebook/201909/programming_languag…