• 我从0开始开发了一个LDAP服务。


    当然不能从0开始,,,我当初酝酿这个需求的时候,LDAP的rfc都看了一周。

    需求是需要一个LDAP服务来支持三方系统的登录,比如神策、confluence、jira。

    都不用想,三方开源闭源的方案都有很多。但是我寻觅了一圈,没找到一个可以直接在LDAP后端对接一个接口到账号体系的,都是需要账号导入,纳尼?

    哈哈哈,也或许是造轮子的情绪太重,没有认真的找。但是不管怎么样,轮子造出来了。

    我是怎么造的轮子?

    当然是先读书了,rfc是要读个大概的。

    https://www.cnblogs.com/mrtiny/p/ldap-Technical-Specification-Road-Map.html

    协议指令比较多,我们并不关心用不到的,我们只需要支持两个主要的指令,查询(searchrequest)、认证(bindrequest)

    就可以实现需求了。

    LDAP的服务端实现有很多,我选了一个叫OpenLDAP的,因为名字看着顺眼。

    源码是C++的,我开始是用它的数据库结构,并参考代码,用C#实现了对应的账号管理功能,当时的方案是认证时候同步账号到ldap数据库。

    协议解析,也就是将请求数据解析成程序员能看明白的实体对象,也是有开源方案的。

    比如Zetetic的,http://wiki.github.com/skradel/Zetetic.Ldap。

    实际使用时候,发现有很多不完善,解析出错。因此我基于rfc和它的一些类的定义实现了自己的方案。

    主要就是将请求解析成Asn1,然后从Asn1解析出实体对象。

    然后实现会话管理,也就是bindrequest+unbindrequest。

    然后实现ip白名单功能。

    然后设计可以对接外部账号体系的接口。

    上线后完美支撑业务需求。

    我知道它有一些瑕疵,

    比如openldap的表设计在字段中存了sql字句,而我用的EF无法发挥优势。

    比如searchrequest指令处理里面没有实现成员组的支持。

    比如bindrequest指令处理,同步账号又存储到ldap数据库的操作没有多少意义。

    于是在今年底,我又花了大概一周时间,重构了一次:

    干掉之前的ldap数据库临时存储账号的功能,替换为直接对接账号体系接口。

    searchrequest指令处理时的查询缓存优化。

    新增支持账号组。

    开发调试协议是个繁琐的工作,因此我请来了apache目录服务客户端

    对外的接口很简单,实现对应的接口定义就OK,其他的交给框架。

        interface ILdapPersonStore
        {
            List<ILdapExternalObject> GetPersons();
        }
    
        public interface ILdapExternalObject
        {
            Dictionary<string, string> Attributes { get; }
    
            /// <summary>
            /// 记录位置,唯一
            /// </summary>
            /// <returns></returns>
            string GetDN();
            /// <summary>
            /// 所属域
            /// </summary>
            /// <returns></returns>
            string GetDC();
    
    
            /// <summary>
            /// 通用名称
            /// </summary>
            /// <returns></returns>
            string GetCN();
    
            /// <summary>
            /// 类别
            /// </summary>
            /// <returns></returns>
            string GetObjectClass();
        }
        public interface ILdapPerson : ILdapExternalObject
        {
            /// <summary>
            /// 所属组织单元
            /// </summary>
            /// <returns></returns>
            string GetOU();
    
            /// <summary>
            /// 用户ID
            /// </summary>
            /// <returns></returns>
            string GetUID();
            /// <summary>
            /// 
            /// </summary>
            /// <returns></returns>
            string GetMemberOf();
            /// <summary>
            /// UUID格式的唯一标识
            /// </summary>
            /// <returns></returns>
            string GetEntryUUID();
            /// <summary>
            /// 姓名
            /// </summary>
            /// <returns></returns>
            string GetName();
            /// <summary>
            /// 是否有下级
            /// </summary>
            /// <returns></returns>
            bool GetHasSubordinates();
    
            ILdapExternalObject groupOfUniqueNames { get; }
        }
    

    轮子造好就等卖钱了

  • 相关阅读:
    Android -- 经验分享
    Android -- 获取汉字的首字母
    Android -- PowerManager和PowerManager.WakeLock
    内存堆和栈的区别
    Java BigDecimal大数字操作
    myqsl for C# 驱动包下载地址-官网
    ASP.NET 查询客户端请求IP地址
    Chapter 6 — Improving ASP.NET Performance
    WebSocket 支持的浏览器
    Local System、Local Service與Network Service
  • 原文地址:https://www.cnblogs.com/mrtiny/p/ldap_server_source_code_c_sharp.html
Copyright © 2020-2023  润新知