在 .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" });
我有一种感觉,由于忽略了一些东西,会有一个明显而简单的答案,而且确实有!
我想我找到了解决方案 - 它只是第一个不正确的值 - 如果忽略它,一切正常!
我正在将一些代码从 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" });
我有一种感觉,由于忽略了一些东西,会有一个明显而简单的答案,而且确实有!
我想我找到了解决方案 - 它只是第一个不正确的值 - 如果忽略它,一切正常!