Skip to content

24 .net获取ad信息

Jinxin Chen edited this page Dec 11, 2019 · 1 revision

本文介绍如何在.net环境使用ldap library获取ad信息

windows环境下获取方式

windows可以通过framework的 System.DirectoryServices 来获取 AD 信息,示例代码如下:

string username = ""; // Who has the permission to access the AD
string pwd = ""; //Password for the user
string _path = "LDAP://";

System.DirectoryServices.DirectoryEntry entry = new System.DirectoryServices.DirectoryEntry(_path, username, pwd);
System.DirectoryServices.DirectorySearcher mySearcher = new System.DirectoryServices.DirectorySearcher(entry);
SortOption option = new SortOption("Mail", System.DirectoryServices.SortDirection.Ascending);

mySearcher.PageSize = 100;
mySearcher.Sort = option;
mySearcher.Filter = ($"(&(objectClass=user)(department=)(mail=");

var results = mySearcher.FindAll();

// 获取属性值:
foreach(var result in results)
{
    var account = de.Properties["sAMAccountName"].Value as string;
    var sid = new System.Security.Principal.SecurityIdentifier(de.Properties["objectSid"].Value as byte[], 0);
}

这里设定了分页,对于数据量大的ad,也可以正常获取到全部的资料

linux环境下获取方式

linux可以通过 Novell.Directory.Ldap.NETStandard 来获取 AD 信息,示例代码如下:

    LdapSearchConstraints cons = new LdapSearchConstraints
    {
        MaxResults = 0,
        BatchSize = 1000,
        ReferralFollowing = false
    };

    var ldapConn = CreateLdapConnection();
    var attr = new string[] { "sAMAccountName", "mail", "displayName", "memberOf" };
    var searchBase = string.Empty;

    // (!(UserAccountControl:1.2.840.113556.1.4.803:=2)) means except disabled users
    string filter = $"(&(objectCategory=person)(objectClass=user)(!(UserAccountControl:1.2.840.113556.1.4.803:=2))(mail=*))";

    var search = ldapConn.Search(searchBase, LdapConnection.SCOPE_SUB, filter, attr, false, cons);
    var nextEntries = search.ToList();

    // get attributes
    foreach(var nextEntry in nextEntries)
    {
        nextEntry.getAttributeSet();
        var userId = nextEntry.DN;
        var account = nextEntry.getAttribute("sAMAccountName").StringValue;
        var email = nextEntry.getAttribute("mail").StringValue;
        var userDisplayName = nextEntry.getAttribute("displayName").StringValue;
        var sid = new System.Security.Principal.SecurityIdentifier((byte[])(Array)groupEntry.getAttribute("objectSid").ByteValue, 0).Value;
    }

private LdapConnection CreateLdapConnection()
{

    // Creating an LdapConnection instance 
    var ldapConn = new LdapConnection() { SecureSocketLayer = false };

    //Connect function will create a socket connection to the server - Port 389 for insecure and 3269 for secure    
    ldapConn.Connect(_ldapSetting.Server, _ldapSetting.Port);

    //Bind function with null user dn and password value will perform anonymous bind to LDAP server 
    ldapConn.Bind(_ldapSetting.Username, _ldapSetting.Password);

    return ldapConn;
}

实测数据超过 10000 时,会返回 sizelimited 的 exception,即使有设定 MaxResults=0,可以采取一些workaround方法分批次取数据,比如:

for (var start = 'a'; start <= 'z'; start++)
{
    var searchBase = string.Empty;
    string filter = $"(&(objectCategory=person)(objectClass=user)(!(UserAccountControl:1.2.840.113556.1.4.803:=2))(mail={start}*@163.com))";

    var search = ldapConn.Search(searchBase, LdapConnection.SCOPE_SUB, filter, attr, false, cons);
    var nextEntries = search.ToList();
}

获取 user 所属 group 的信息:

foreach (var department in nextEntry.getAttribute("memberOf").StringValueArray)
{
    var groupEntry = ldapConn.Read(department);
}

参考

Clone this wiki locally