[C#] AD串接(LDAP/LDAPS)

  • 684
  • 0
  • AD
  • 2023-09-15

近期有串接AD的機會,因此嘗試了一下幾種寫法。

本次嘗試了以下四種簡單的寫法

  1. .Net Framework LDAP連線
  2. .Net Framework LDAPS連線
  3. .Net 6 LDAP連線
  4. .Net 6 LDAPS連線

.Net Framework LDAP連線

【開發環境】
開發工具:Visual Studio 2022
Framework:.Net Framework 4.7.2

【範例程式】

以下是使用LdapConnection建立與AD連線的範例:

//LdapDirectoryIdentifier裡面填寫AD的網址
using (var ldapConnection = new LdapConnection(new LdapDirectoryIdentifier("example.com")))
{
    //設定要使用的LDAP通訊協定版本
    ldapConnection.SessionOptions.ProtocolVersion = 3;
    //如果啟用 Secure Sockets Layer,則這個屬性為 true,否則為 false
    ldapConnection.SessionOptions.SecureSocketLayer = false;
    //LDAP登入身份, 若設定為Anonymous則為匿名登入
    ldapConnection.AuthType = AuthType.Negotiate; //AuthType.Negotiate,AuthType.Basic;
    //設定登入帳號&密碼
    ldapConnection.Credential = new NetworkCredential("登入帳號", "登入密碼");
    //連線
    ldapConnection.Bind();
    Console.WriteLine("Successfully authenticated to ldap server " + domain);
}

連線建立完成後可以撈取想要的屬性

//設定過濾字串
string searchFilter = $"(&(objectClass=user)(|(cn={登入帳號})))";
//設定要取回的屬性資料
string[] attrList = new string[] { "memberOf", "displayName", "department", "mail" };

SearchRequest searchRequest = new SearchRequest("OU=Users,DC=example,DC=com", searchFilter, SearchScope.Subtree, attrList);
Console.WriteLine("Start SendRequest...");
var response = (SearchResponse)ldapConnection.SendRequest(searchRequest);
var entry = response.Entries[0];
if (entry != null)
{
    foreach (string attr in attrList)
    {
        DirectoryAttribute attrs = entry.Attributes[attr];
        if (attrs != null)
        {
        	//屬性可能有多個值
            foreach (var attrItem in attrs.GetValues(typeof(String)))
            {
                Console.WriteLine($"{attrs.Name} = {attrItem.ToString()}");
            }
        }
    }
}
else Console.WriteLine("Entry is empty.");

.Net Framework LDAPS連線

【開發環境】
開發工具:Visual Studio 2022
Framework:.Net Framework 4.7.2

【範例程式】

需要修改的地方有幾個:

1.AD網址須加上Port 636。

using (var ldapConnection = new LdapConnection(new LdapDirectoryIdentifier("example.com:636")))

2.啟用 Secure Sockets Layer

ldapConnection.SessionOptions.SecureSocketLayer = true;

3.新增VerifyServerCertificate

ldapConnection.SessionOptions.VerifyServerCertificate += delegate { return true; };

4.填寫完整帳號

ldapConnection.Credential = new NetworkCredential("登入帳號@example.com", "登入密碼");

撈取的範例同LDAP,LDAPS完整連線程式如下:

// 1. AD網址須加上Port 636
using (var ldapConnection = new LdapConnection(new LdapDirectoryIdentifier("example.com:636")))
{
    ldapConnection.SessionOptions.ProtocolVersion = 3;
    // 2. 啟用 Secure Sockets Layer
    ldapConnection.SessionOptions.SecureSocketLayer = true;
    // 3. 新增VerifyServerCertificate
    ldapConnection.SessionOptions.VerifyServerCertificate += delegate { return true; };
    ldapConnection.AuthType = AuthType.Negotiate;
    // 4. 填寫完整帳號
    ldapConnection.Credential = new NetworkCredential($"登入帳號@example.com", "登入密碼");
    ldapConnection.Bind();
}

.Net 6 LDAP連線

【開發環境】
開發工具:Visual Studio 2022
Framework:.Net 6
套件:Novell.Directory.Ldap.NETStandard

【範例程式】

使用套件建立連線程式碼就簡單許多,短短幾行就完成連線建立。

using (var ldapConnection = new LdapConnection())
{
    ldapConnection.Connect("example.com", 389);
    ldapConnection.Bind("example\\登入帳號", "登入密碼");
}

查詢資料部份如下。

//設定過濾字串
string searchFilter = $"(&(objectClass=user)(|(cn=登入帳號)))";
//設定要取回的屬性資料
string[] attrList = new string[] { "memberOf", "displayName", "department", "mail"};

Console.WriteLine("Start Search...");
LdapSearchResults searchResults = (LdapSearchResults)ldapConnection.Search("OU=Users,DC=example,DC=com", LdapConnection.ScopeSub, searchFilter, attrList,false);

while (searchResults.HasMore())
{
    LdapEntry entry = searchResults.Next();
    if (entry != null)
    {
        foreach (var item in entry.GetAttributeSet())
        {
        	//屬性可能有多個值
            foreach(var itemVal in item.StringValueArray)
            {
                Console.WriteLine($"{item.Name} = {itemVal}");
            }
        }
    }
    else Console.WriteLine("Entry is empty.");
}

.Net 6 LDAPS連線

【開發環境】
開發工具:Visual Studio 2022
Framework:.Net 6
套件:Novell.Directory.Ldap.NETStandard

【範例程式】

改為LDAPS連線要修改的地方如下:

1.啟用Secure Socket Layer

ldapConnection.SecureSocketLayer = true;

2.調整連線Port改為636

ldapConnection.Connect("example.com", 636);

使用套件真的很方便,LDAP要改為LDAPS也只需要修改一點點地方就完成了,連線程式如下:

using (var ldapConnection = new LdapConnection())
{
	// 1. 啟用Secure Socket Layer
	ldapConnection.SecureSocketLayer = true;
	// 2. 調整連線Port改為636
    ldapConnection.Connect("example.com", 636);
    ldapConnection.Bind("example\\登入帳號", "登入密碼");
}

【後記】

當初在寫LDAPS時公司居然沒一個前輩可以請教,網路上找的資訊也是片片段段,所以先稍微記了一下,後來發現程式碼架構大致相同,但不同公司似乎值會有些許不同,各位真要使用還是要稍微調整一下喔!