我从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; }
}
轮子造好就等卖钱了

浙公网安备 33010602011771号