C# -- Novell.Directory.Ldap连接LDAP作简单筛选查询,并处理objectGUID的乱码问题

什么是LDAP

LDAP是轻量目录访问协议(Lightweight Directory Access Protocol)的缩写,LDAP是从X.500目录访问协议的基础上发展过来的,目前的版本是v3.0。与LDAP一样提供类似的目录服务软件还有ApacheDS、Active Directory、Red Hat Directory Service 。

LDAP的特点

LDAP作为一个是轻量目录服务软件,与关系型数据库不同,它有很好的读性能,当读写比大于7:1的时候,就可以考虑使用LDAP存储数据。但是写性能很差,所以不擅长处理频繁的修改的插入,并且没有事务处理、和回滚等功能。

LDAP提供静态数据的快速查询方式

Client/Server模型,Server 用于存储数据,Client提供操作目录信息树的工具

这些工具可以将数据库的内容以文本格式(LDAP 数据交换格式,LDIF)呈现在您的面前

LDAP是一种开放Internet标准,LDAP协议是跨平台的Interent协议

一般会将认证用户信息放在LDAP中,例如单位人员的信息,按照单位部门层级创建目录,并将人员信息存放在相应的目录下。但是因为目录服务不是像关系型数据库的表格结构,所以查询时不能使用SQL语句。

C#链接LDAP

本文中采用的是使用开源工具 Novell.Directory.Ldap ,可以在 Nuget 中下载包使用

还有一种比较简单的连接方式,安装使用 System.DirectoryServices 包,使用方法可以自行百度。
DirectoryServices 有一个优点,其读取并显示出的信息和 LDAP 中是一样的,基本不需要额外的转化操作。
比如 LDAP 中的 objectGUID一般是以 octetString 类型存储的,我们从 DirectoryEntry 中的 Properties 中获取的 objectGUID 和 LDAP 中的 objectGUID 是一致的,不存在乱码的情况
但是 Novell.Directory.Ldap 中读取的 obejctGUID 的 StringValue 会存在乱码的情况,但是其实际值是正确的,我们可以根据它返回的 ByteValue 自行解析

那么为什么不使用 DirectorySearcher呢?因为它不支持 LINUX 平台。

代码

在这做一个简单的接口

        private string Domin = "aaa";//域名称
        private string Host = "aaa.bb.cc";//域服务器地址
        private int Port = 389;///端口
        private string BaseDc = "DC=aaa,DC=bb,DC=cc";//根据上面的与服务器地址 拆分DC
        private string User = "xxxxxx";//用户名
        private string Password = "xxx";//密码
        
        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="user">用户信息</param>
        /// <returns>用户结果集</returns>
        [HttpGet]
        public Dictionary<string,object> GetUserByName(User user)
        {
            Dictionary<string, object> rs = new Dictionary<string, object>();

			//用户结果集
            List<User> result = new List<User>();
            
            //默认响应结果
            rs.Add("code", 500);
            rs.Add("msg", "接口异常"); 
            rs.Add("data", result);
            rs.Add("success", false);

            if (null != user)
            {
                try
                {
                    //初始化链接
                    using (var ldapConnection = new LdapConnection())
                    {
                        //链接
                        ldapConnection.Connect(Host, Port);

						//使用指定的认证信息发送 LDAP 绑定。
                        ldapConnection.Bind(Domin + "\\" + User, Password);
                        
                        //过滤条件
                        string filter = "(&(objectClass=user)";
                        if (null != user.realname && !"".Equals(user.realname))
                        {
                            filter += "(name=*" + user.realname + "*)";
                        }
                        if (null != user.email && !"".Equals(user.email))
                        {
                            filter += "(mail=*" + user.email + "*)";
                        }
                        filter += ")";

	                    //设置查询条件 在这里我们只要返回 用户 guid、name、mail就可以了
                        var entities = ldapConnection.Search(BaseDc, LdapConnection.ScopeSub,filter,new string[] { "objectGUID","name","mail"}, false);
                        
                        //循环结果集
                        while (entities.HasMore())
                        {
                            try
                            {
                                LdapEntry entity = entities.Next();
                                User useri = new User();
                                foreach (var item in entity.GetAttributeSet()) {
                                    if ("name"==item.Name)
                                    {
                                        useri.realname = item.StringValue;
                                    }
                                    else if("mail"==item.Name)
                                    {
                                        useri.email = item.StringValue;
                                    }
                                    else if ("objectGUID"==item.Name)
                                    {
                                    	//处理objectGUID乱码
                                        string guid = OctetStringToString(item.ByteValue) ;
                                        useri.id = guid;
                                    }
                                }
                                result.Add(useri);
                            }
                            catch (Exception ex)
                            {
                            }
                        }

                        rs["code"] = 200;
                        rs["msg"] = "";
                        rs["data"] = result;
                        rs["success"] = true;
                    }
                }
                catch (Exception err)
                {
                    rs["msg"] = err.Message;
                }
            }
            return rs;
        }

        /// <summary>
        /// 网上找的方法
        /// 解析拼接 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx
        /// </summary>
        /// <param name="GUID"></param>
        /// <returns></returns>
        private string OctetStringToString(byte[] GUID)
        {
            String strGUID = "";
            String byteGUID = "";

            for (int c = 0; c < GUID.Length; c++)
            {
                byteGUID = byteGUID + "\\" + AddLeadingZero((int)GUID[c] & 0xFF);
            }
            strGUID = "";
            strGUID = strGUID + AddLeadingZero((int)GUID[3] & 0xFF);
            strGUID = strGUID + AddLeadingZero((int)GUID[2] & 0xFF);
            strGUID = strGUID + AddLeadingZero((int)GUID[1] & 0xFF);
            strGUID = strGUID + AddLeadingZero((int)GUID[0] & 0xFF);
            strGUID = strGUID + "-";
            strGUID = strGUID + AddLeadingZero((int)GUID[5] & 0xFF);
            strGUID = strGUID + AddLeadingZero((int)GUID[4] & 0xFF);
            strGUID = strGUID + "-";
            strGUID = strGUID + AddLeadingZero((int)GUID[7] & 0xFF);
            strGUID = strGUID + AddLeadingZero((int)GUID[6] & 0xFF);
            strGUID = strGUID + "-";
            strGUID = strGUID + AddLeadingZero((int)GUID[8] & 0xFF);
            strGUID = strGUID + AddLeadingZero((int)GUID[9] & 0xFF);
            strGUID = strGUID + "-";
            strGUID = strGUID + AddLeadingZero((int)GUID[10] & 0xFF);
            strGUID = strGUID + AddLeadingZero((int)GUID[11] & 0xFF);
            strGUID = strGUID + AddLeadingZero((int)GUID[12] & 0xFF);
            strGUID = strGUID + AddLeadingZero((int)GUID[13] & 0xFF);
            strGUID = strGUID + AddLeadingZero((int)GUID[14] & 0xFF);
            strGUID = strGUID + AddLeadingZero((int)GUID[15] & 0xFF);
            
            return strGUID;
        }

        /// <summary>
        /// 长度不足补零
        /// </summary>
        /// <param name="k"></param>
        /// <returns></returns>
        private static String AddLeadingZero(int k)
        {
            return (k <= 0xF)?"0"+Int2String(k): Int2String(k);
        }

        /// <summary>
        /// int 转 hexstring
        /// </summary>
        /// <param name="kb"></param>
        /// <returns></returns>
        private static string Int2String(int kb)
        {
            byte[] bytes = new byte[1];
            bytes[0] = (byte)(kb & 0xFF);
            string S = Convert.ToHexString(bytes);
            return S;
        }

Linux 安装.NetCore环境

因为我使用的是内网服务器,这里主要记录一下离线环境的配置,在线安装直接使用 yum instyall 安装各种环境即可

  • 下载安装包 ,我选择的是 .NET 6.0.101 ,X64版本

https://dotnet.microsoft.com/en-us/download/dotnet/6.0

  • LINUX 服务器创建文件夹

mkdir /home/dotnet

  • 上传文件到创建的文件夹里面
  • 解压文件

tar zxvf dotnet-sdk-6.0.101-linux-x64.tar.gz

  • 创建软连接

ln -s /home/dotnet/dotnet /usr/bin

  • 测试dotnet环境

dotnet --version
正常打印dotnet版本即表示安装成功。

.NetCore WebApi 部署

  • 发布项目 打包到 myproject 文件夹
  • 上传服务器 /home/dotnet_project 文件夹下
  • 执行命令

dotnet /home/dotnet_project/myproject/myWebApi.dll
添加参数 --urls = http://0.0.0.0:8800 指定端口(可以在appSetting.json中配置 urls )

  • 测试端口

curl http://127.0.0.1:8800/api/Ldap/get
curl -X POST --header “Content-Type: application/json” -d {“name”:“小明”} http://127.0.0.1:8800/api/Ldap/getUserByName

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mingvvv

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值