在 .NET5 中使用 System.DirectoryServices.Protocols 获取 LDAP 令牌组

Get LDAP TokenGroups using System.DirectoryServices.Protocols in .NET5

我正在将一些代码从 System.DirectoryServices 移植到 System.DirectoryServices.Protocols,因为需要在 linux 上 运行。

大部分代码都很好,但是检索 tokenGroups 的这一小段代码没有被理解。

原代码如下:

using (var ldapObject = new DirectoryEntry(objectPath, username, password, AuthenticationTypes.Secure))
        {
            ldapObject.Options.Referral = ReferralChasingOption.All;
            ldapObject.RefreshCache(new string[] { "tokenGroups" });
            foreach (byte[] sid in ldapObject.Properties["tokenGroups"])
            {
                // Won't run on linux
                var groupSID = new System.Security.Principal.SecurityIdentifier(sid, 0).ToString();
                try
                {
                    var group = this.GetSecurityGroupBySID(groupSID);
                }
                catch (Exception ex)
                {
                    log.Warn($"Failed to get group with SID {groupSID}", ex);
                }
            }
        }

其中 objectPath 的形式为 $"LDAP://{domainName}/{distinguishedName}"

我的尝试是这样的:

public void GetExpandedGroups(string objectMail, LdapConnection ldapConnection)
        {
            var usersPath = "OU=active,OU=users,DC=path,DC=etc"; //Not real values
            var filter = $"(&(objectClass = user)(!userAccountControl:1.2.840.113556.1.4.803:= 2)(mail={objectMail}))";
            var request = new SearchRequest(usersPath, filter, SearchScope.Subtree, new string[] { "tokenGroups" });
            request.Controls.Add(new SecurityDescriptorFlagControl(SecurityMasks.Dacl | SecurityMasks.Group | SecurityMasks.Owner));

            var ldapObject = (SearchResponse)ldapConnection.SendRequest(request); // Error thrown here

            foreach (byte[] sid in ldapObject.Entries[0].Attributes["tokenGroups"])
            {
                // Do stuff...
            }
        }

每当这个 运行s 我得到一个错误,抛出。堆栈跟踪和错误响应如下:

   at System.DirectoryServices.Protocols.LdapConnection.<ConstructResponseAsync>d__57.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
   at System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request, TimeSpan requestTimeout)
   at System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request)
   at LDAPTesting.Connectors.Protocols.GetExpandedGroups(String objectMail, LdapConnection ldapConnection) in C:\code\LDAPTesting\LDAPTesting\Connectors\Protocols.cs:line 62
   at LDAPTesting.Connectors.Protocols.GetGroups() in C:\code\LDAPTesting\LDAPTesting\Connectors\Protocols.cs:line 103
   at LDAPTesting.Program.Main(String[] args) in C:\code\LDAPTesting\LDAPTesting\Program.cs:line 17
00002120: SvcErr: DSID-031404CC, problem 5012 (DIR_ERROR), data 0

我的想法是我正在查询错误的路径,但它看起来与原始代码请求的路径相匹配,所以我不确定我还遗漏了什么。

对于遇到这种情况的任何人来说,解决方案都非常简单。

SearchRequest 对象需要在 Base 范围内。阅读错误消息时真的很明显。所以行:

var request = new SearchRequest(usersPath, filter, SearchScope.Subtree, new string[] { "tokenGroups" });

应该改为:

var request = new SearchRequest(usersPath, filter, SearchScope.Base, new string[] { "tokenGroups" });

我有一种感觉,由于忽略了一些东西,会有一个明显而简单的答案,而且确实有!

我想我找到了解决方案 - 它只是第一个不正确的值 - 如果忽略它,一切正常!