dotNET Core 中怎样操作AD(续1)

在之前的文章《dotNET Core 中怎样操作 AD?》中主要以AD的数据同步到数据库的场景来描述了在 dotNetCore 中怎样操作AD,本文将继续介绍一些在 dotNetCore 中操作 AD 的其他常用操作。

环境

  • dotNET Core:3.0

  • Novell.Directory.Ldap.NETStandard2_0:3.1.0

  • AD:windows server 2012

基本操作

查询

在 AD 中进行用户的操作,通常需要先判断用户是否存在,这时就需要使用查询了,用下面代码可以进行 AD 中的查询:

 var entities = _connection.Search(ADClient.BaseDC,LdapConnection.SCOPE_SUB,$"sAMAccountName={loginName}",null, false);

参数说明:

  • base: 指定的总体搜索范围,通常在创建连接时会指定一个 BaseDC,表示后面的操作在此 DC 范围内,如果希望从根开始搜索,此参数可传空

  • scope:查询遍历的方式,分为 SCOPE_BASE 、SCOPE_ONE 和 SCOPE_SUB 三种

    • SCOPE_BASE:通常知道对象的 DN,并希望获取其属性时,使用此项

    • SCOPE_ONE:查询 base 的下一层级

    • SCOPE_SUB:查询 base 下的所有对象,包含 base

  • filter:用来过滤的表达式,下面列出一些常用的表达式

    (cn=oec2003):返回 cn 等于 oec2003 的用户
    (sAMAccountName=oec*):返回登录名以 oec 开头的用户
    !(cn=oec2003):返回 cn 不等于 oec2003 的用户
    (|(cn=oec2003)(telephonenumber=888*)):返回 cn 等于 oec2003 ,或者电话号码以 888 开头的用户
    (&(cn=oec2003)(telephonenumber=888*)):返回 cn 等于 oec2003 ,并且电话号码以 888 开头的用户
    

    其他更多的表达式可以参考官方文档:https://www.novell.com/documentation/developer/ldapcsharp/?page=/documentation/developer/ldapcsharp/cnet/data/bovtuda.html

  • attrs:字符串数组,可以指定返回的属性的列表,不指定返回所有的属性

例如根据登录名来查询用户的示例代码如下:

public static LdapEntry GetUser(string loginName)
{var entities = _connection.Search(ADClient.BaseDC,LdapConnection.SCOPE_SUB,$"sAMAccountName={loginName}",null, false);LdapEntry entry = null;while (entities.HasMore()){try{entry = entities.Next();}catch (LdapException e){Console.WriteLine($"GetUser Error: {e.Message}");continue;}}return entry;
}

添加用户

public static bool AddUser(string userName, string loginName, string defaultPwd, string container)
{//设置默认密码defaultPwd = $"\"{defaultPwd}\"";sbyte[] encodedBytes = SupportClass.ToSByteArray(Encoding.Unicode.GetBytes(defaultPwd));LdapAttributeSet attributeSet = new LdapAttributeSet();attributeSet.Add(new LdapAttribute("objectclass", "user"));attributeSet.Add(new LdapAttribute("sAMAccountName", userName));//设置创建用户后启用attributeSet.Add(new LdapAttribute("userAccountControl", (66080).ToString()));attributeSet.Add(new LdapAttribute("unicodePwd", encodedBytes));string dn = $"CN={loginName},{container}";LdapEntry newEntry = new LdapEntry(dn, attributeSet);_connection.Add(newEntry);return true;
}

注意点:

  • 默认密码的设置需要给密码加上引号

  • 默认情况下创建的用户是禁用的,如果要启用需要加上代码attributeSet.Add(new LdapAttribute("userAccountControl", (66080).ToString()));

修改密码

public static bool UpdatePassword(string loginName, string password)
{LdapEntry entry = GetUser(loginName);if (entry == null){throw new Exception($"名为:{loginName} 的用户在AD中不存在");}password = $"\"{password}\"";sbyte[] encodedBytes = SupportClass.ToSByteArray(Encoding.Unicode.GetBytes(password));LdapAttribute attributePassword = new LdapAttribute("unicodePwd", encodedBytes);_connection.Modify(entry.DN, new LdapModification(LdapModification.REPLACE, attributePassword));return true;
}

禁用用户

public static bool EnblaedUser(string loginName)
{LdapEntry entry = GetUser(loginName);if (entry == null){throw new Exception($"名为:{loginName} 的用户在AD中不存在");}LdapAttribute attributePassword = new LdapAttribute("userAccountControl", (66082).ToString());_connection.Modify(entry.DN, new LdapModification(LdapModification.REPLACE, attributePassword));return true;
}

启用用户

public static bool EnblaedUser(string loginName)
{LdapEntry entry = GetUser(loginName);if (entry == null){throw new Exception($"名为:{loginName} 的用户在AD中不存在");}LdapAttribute attributePassword = new LdapAttribute("userAccountControl", (66080).ToString());_connection.Modify(entry.DN, new LdapModification(LdapModification.REPLACE, attributePassword));return true;
}

移动用户到新的 OU

public static bool MoveUserToOU(string loginName, string rcn = "", string ouContainer = "")
{LdapEntry entry = GetUser(loginName);if (entry == null){throw new Exception($"名为:{loginName} 的用户在AD中不存在");}string cn = entry.AttrStringValue("cn");cn = rcn == "" ? cn : rcn;string newRCN = $"CN={cn}";if (string.IsNullOrWhiteSpace(ouContainer)){_connection.Rename(entry.DN, newRCN, true);}else{_connection.Rename(entry.DN, newRCN, ouContainer, true);}return true;
}

注意点:

  • 一个用户一旦创建,DN 是不能修改的,可以通过Rename方法来修改 CN 来达到修改 DN 的目的

  • 如果传入第三个参数ouContainer,就可以实现将用户移动到目标 OU

添加用户到组

public static bool AddUserToGroup(string loginName, string groupDN)
{LdapEntry entry = GetUser(loginName);if (entry == null){throw new Exception($"名为:{loginName} 的用户在AD中不存在");}List<string> memberOf = entry.AttrStringValueArray("memberOf");if (memberOf.Contains(groupDN)){throw new Exception($"名为:{loginName} 的用户已经加入了组: {groupDN}");}LdapModification[] modGroup = new LdapModification[1];LdapAttribute member = new LdapAttribute("member", entry.DN);modGroup[0] = new LdapModification(LdapModification.ADD, member);try{_connection.Modify(groupDN, modGroup);}catch (LdapException e){System.Console.Error.WriteLine("Failed to modify group's attributes: " + e.LdapErrorMessage);return false;}catch (Exception e){Console.Error.WriteLine("AddUserToGroup Error:" + e.Message);return false;}return true;
}

用户从组中移除

public static bool RemoveUserFromGroup(string loginName, string groupDN)
{LdapEntry entry = GetUser(loginName);if (entry == null){throw new Exception($"名为:{loginName} 的用户在AD中不存在");}List<string> memberOf = entry.AttrStringValueArray("memberOf");if (!memberOf.Contains(groupDN)){throw new Exception($"名为:{loginName} 的用户不存在于组: {groupDN} 中");}LdapModification[] modGroup = new LdapModification[1];LdapAttribute member = new LdapAttribute("member", entry.DN);modGroup[0] = new LdapModification(LdapModification.DELETE, member);try{_connection.Modify(groupDN, modGroup);}catch (LdapException e){System.Console.Error.WriteLine("Failed to delete group's attributes: " + e.LdapErrorMessage);return false;}catch (Exception e){Console.Error.WriteLine("RemoveUserFromGroup Error:" + e.Message);return false;}return true;
}

添加用户登录到

public static bool UpdateUserWorkStation(string loginName, string computerName, UserWorkStationOperType type)
{LdapEntry entry = GetUser(loginName);if (entry == null){throw new Exception($"名为:{loginName} 的用户在AD中不存在");}List<string> stations = entry.AttrStringValue("userWorkstations").Split(',').ToList();if (type == UserWorkStationOperType.Add && !stations.Contains(computerName)){stations.Add(computerName);}else if (type == UserWorkStationOperType.Remove && stations.Contains(computerName)){stations.Remove(computerName);}LdapAttribute attributePassword = new LdapAttribute("userWorkstations", string.Join(',', stations));_connection.Modify(entry.DN, new LdapModification(LdapModification.REPLACE, attributePassword));return true;
}

最后

本文的示例代码已推送到 GitHub:https://github.com/oec2003/DotNetCoreAdDemo

官网也有些示例,但不是很完善,而且有很多代码并不能正常执行(可能跟 AD 的版本有关),所以才有了本示例。本示例也会添加更多的使用场景,不断完善。

希望本文对您有所帮助。

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

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

相关文章

蓝桥杯2015初赛-奇妙的数字

题目描述 小明发现了一个奇妙的数字。它的平方和立方正好把0~9的10个数字每个用且只用了一次。你能猜出这个数字是多少吗&#xff1f; 输出 请输出该数字&#xff0c;不要输出任何多余的内容。 代码如下&#xff1a; #include <iostream> using namespace std; #inc…

Elastic发布K8s部署和控制数据管理工具官方解决方案

用于搜寻企业内部数据的搜寻引擎Elasticsearch开发商Elastic&#xff0c;发布了可在Kubernetes上部署Elastic Cloud的工具ECK 1.0。ECK向用户提供一个官方解决方案&#xff0c;来调度Kubernetes上的Elasticsearch&#xff0c;并让Kubernetes上的Elastic产品&#xff0c;能够以类…

如何启动和关闭oracle数据库,Oracle数据库启动和关闭方式总结

Oracle数据库启动和关闭的方法很多&#xff0c;下面就为您详细介绍几种常用的Oracle数据库启动和关闭方式&#xff0c;供您参考学习之用。一、几种Oracle数据库启动方式&#xff1a;1、startup nomount非安装启动&#xff0c;这种方式启动下可执行&#xff1a;重建控制文件、重…

蓝桥杯2015初赛-牌型种数-dfs

题目描述 小明被劫持到X赌城&#xff0c;被迫与其他3人玩牌。 一副扑克牌&#xff08;去掉大小王牌&#xff0c;共52张&#xff09;&#xff0c;均匀发给4个人&#xff0c;每个人13张。 这时&#xff0c;小明脑子里突然冒出一个问题&#xff1a; 如果不考虑花色&#xff0c;只…

【Magicodes.IE 2.0.0-beta1版本发布】已支持数据表格、列筛选器和Sheet拆分

为了更好的完善Magicodes.IE&#xff0c;春节期间我们会进行一次大的重构。由于精力有限&#xff0c;急缺文档和翻译&#xff08;将文档翻译为英文文档&#xff09;支持&#xff0c;诚邀各位加入。同时在功能方便也做了相关规划&#xff0c;有兴趣的朋友可以参与提交PR。https:…

oracle 取英文排序,Oracle中中文、数字,英文混杂形式的字段进行排序的方法

http://blog.csdn.net/p451933505/article/details/9272257对Oracle中中文、数字、英文混杂形式的字段进行排序的方法&#xff1a;例如&#xff1a;order by NLSSORT(字段名,‘NLS_SORT SCHINESE_PINYIN_M‘), to_number(translate(字段名, ‘0123456789‘ || 字段名, ‘01234…

蓝桥杯2015初赛-饮料换购-枚举

题目描述 乐羊羊饮料厂正在举办一次促销优惠活动。 乐羊羊C型饮料&#xff0c;凭3个瓶盖可以再换一瓶C型饮料&#xff0c;并且可以一直循环下去(但不允许暂借或赊账)。 请你计算一下&#xff0c;如果小明不浪费瓶盖&#xff0c;尽量地参加活动。 那么&#xff0c;对于他初始买…

Mbp,一个用于学习.net core的开发框架

Mbp(https://github.com/mbpframework/Mbp)是一个.net core 3的企业级web开发框架,是我个人用于学习.net core而发起的一个开源项目.这个借鉴了国外优秀开源项目abp vnext,及国内优秀开源框架Osharp的一些思想和实现.欢迎各路开发爱好者加入这个项目,一起学习,一起玩耍,共同成长…

oracle 每日归档量,小知识:统计Oracle的日归档量

首先这对于Oracle DBA来说是个初级问题&#xff0c;即使不熟悉的初级DBA也可以快速在网上搜索到现成的SQL语句。网上搜到的查询SQL基本类似这样的逻辑&#xff1a;select trunc(completion_time) "Date", count(*) cnt, round(sum(block_size * blocks / 1024 / 1024…

蓝桥杯2015初赛-奖券数目-枚举

题目描述 有些人很迷信数字&#xff0c;比如带“4”的数字&#xff0c;认为和“死”谐音&#xff0c;就觉得不吉利。 虽然这些说法纯属无稽之谈&#xff0c;但有时还要迎合大众的需求。 某抽奖活动奖券号码是5位数(10000-99999)&#xff0c;要求其中不要出现带“4”的号码。 主…

什么?原来C#还有这两个关键字

系列介绍简介【五分钟的dotnet】是一个利用您的碎片化时间来学习和丰富.net知识的博文系列。它所包含了.net体系中可能会涉及到的方方面面&#xff0c;比如C#的小细节&#xff0c;AspnetCore&#xff0c;微服务中的.net知识等等。场景您可以在下班坐地铁的时候&#xff0c;拿出…

php files得不到导入的文件,PHP判断文件是否被引入的方法get_included_files用法示例...

本文实例讲述了PHP判断文件是否被引入的方法get_included_files用法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;// 本文件是 abc.phpinclude test1.php;include_once test2.php;require test3.php;require_once test4.php;$included_files get_included_files();…

蓝桥杯2015初赛-三羊献瑞-枚举

题目描述 观察下面的加法算式&#xff1a; 其中&#xff0c;相同的汉字代表相同的数字&#xff0c;不同的汉字代表不同的数字。 请你填写“三羊献瑞”所代表的4位数字&#xff08;答案唯一&#xff09;&#xff0c;不要填写任何多余内容。 输出 请你填写“三羊献瑞”所代表…

linux系统中变量,Linux系统中的环境变量知识详解

对于没有使用过linux系统的用户来说&#xff0c;有很多术语和功能都很陌生。本文就介绍了linux系统中的环境变量的相关知识&#xff0c;具体内容如下所述。linux是一个多用户的操作系统。每个用户登录系统后&#xff0c;都会有一个专用的运行环境。通常每个用户默认的环境都是相…

如何利用Serilog的RequestLogging来精简ASP.NET Core的日志输出

这是该系列的第一篇文章&#xff1a;在ASP.NET Core 3.0中使用Serilog.AspNetCore。第1部分-使用Serilog RequestLogging来简化ASP.NET Core的日志输出&#xff08;本篇文章&#xff09;第2部分-使用Serilog记录所选的端点名称[敬请期待]第3部分-使用Serilog.AspNetCore记录MVC…

蓝桥杯2015初赛-加法变乘法-枚举

题目描述 我们都知道&#xff1a;123 … 49 1225 现在要求你把其中两个不相邻的加号变成乘号&#xff0c;使得结果为2015 比如&#xff1a; 123…101112…272829…49 2015 就是符合要求的答案。 请你寻找另外一个可能的答案&#xff0c;并把位置靠前的那个乘号左边的数字提…

linux 如何赋值目录,Linux文件系统之目录的建立

一&#xff1a;前言在用户空间中&#xff0c;建立目录所用的API为mkdir().它在内核中的系统调用入口是sys_mkdir().今天跟踪一下函数来分析linux文件系统中目录的建立过程.二&#xff1a;sys_mkdir()Sys_mkdir()对应的代码如下&#xff1a;asmlinkage long sys_mkdir(const cha…

net下的高性能轻量化半自动orm+linq的《SqlBatis》

一、项目介绍该项目内置单表linq操作&#xff0c;xml动态sql解析&#xff0c;词法分析&#xff0c;类型映射等功能。SqlMapper,用来处理sql与数据库操作&#xff0c;它设计的目标是支持mysql,sqlserver,sqllite,pgsql等.TypeMapper用于完成将数据库的字段类型映射到C#类型&…

蓝桥杯2017初赛-迷宫-dfs

题目描述 X星球的一处迷宫游乐场建在某个小山坡上。它是由10x10相互连通的小房间组成的。 房间的地板上写着一个很大的字母。我们假设玩家是面朝上坡的方向站立&#xff0c;则&#xff1a; L表示走到左边的房间&#xff0c;R表示走到右边的房间&#xff0c;U表示走到上坡方向的…

ubuntu系统虚拟机linux系统,基于虚拟机的Linux操作系统安装(Ubuntu

《基于虚拟机的Linux操作系统安装(Ubuntu》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《基于虚拟机的Linux操作系统安装(Ubuntu(13页珍藏版)》请在人人文库网上搜索。1、实验报告1课程名称&#xff1a; Linux程序设计 实验名称&#xff1a;基于虚拟机的Linux操作系…