【问题标题】:.net : How to add a user to a Active Directory Security Group using C#?.net:如何使用 C# 将用户添加到 Active Directory 安全组?
【发布时间】:2019-08-16 00:04:34
【问题描述】:

我正在查找对需要使用以下代码添加用户的安全组的引用:

string strActiveDirectoryPath = @"GC://domain.com";

DirectoryEntry directoryEntryRoot = new DirectoryEntry(strActiveDirectoryPath);

using (DirectorySearcher searcher = new DirectorySearcher(directoryEntryRoot))
{  
    searcher.PageSize = 1000;
    searcher.Filter = "(&(objectClass=group)(cn=*SGNAME*))";
    //searcher.SearchScope = SearchScope.Subtree;
    SearchResult securityGroup = searcher.FindOne();  
}

上面的代码有时会抛出异常说

搜索结果记录过多

我获取安全组的逻辑是否正确?

然后我得到用户的引用并尝试将其添加到安全组:

searcher.Filter = "(SAMAccountName=" + UserAlias + ")";
searcher.PropertiesToLoad.Add("givenname");
searcher.PropertiesToLoad.Add("displayName");               

SearchResult userALias = searcher.FindOne();

DirectoryEntry ent = new DirectoryEntry(securityGroup.Path);              
string domainString = "GC://domain.com/";
int Start =  domainString.Length;
string member = userALias.Path.Substring(domainString.Length);

ent.Properties["member"].Add(member);
// ent.Invoke("Add", new object[] { s });

ent.CommitChanges();
ent.Close();

我创建了一个DirectoryEntry 的实例并提供了我找到的安全组的路径。

应该向DirectoryEntry提供什么?

CommitChanges 失败并出现异常:

服务器不愿意处理请求。

【问题讨论】:

  • 您是否使用.NET Core?
  • @GabrielLuci 我想使用.net core,但我不知道.net core 是否支持目录搜索库
  • 可以,但前提是您安装了仅适用于 Windows 的 Microsoft.Windows.Compatibility NuGet 包。 (您将无法再在任何其他操作系统上运行您的应用)
  • 我之所以问,是因为您同时标记了.net.net-core,但.net 标记仅用于非核心问题。
  • 好的。现在我面临不允许通过 GC 端口进行的错误操作

标签: c# .net .net-core active-directory ldap


【解决方案1】:

我看到了几个问题。第一:

searcher.Filter = "(&(objectClass=group)(cn=*SGNAME*))";
SearchResult securityGroup = searcher.FindOne();

由于您使用的是通配符,因此您正在搜索名称中任何位置带有SGNAME 的任何组。这有两个问题:

  1. 即使cn attribute 已编入索引,也无法使用该索引,因为您在开头使用了通配符。它必须查看 每个 组以尝试找到匹配项。这会减慢您的搜索速度。
  2. 因为您正在进行通配符搜索,它可能匹配多个帐户。 documentation for DirectorySearcher.FindOne() 说:

如果在搜索过程中找到多个条目,则仅返回第一个条目。

所以你不能保证返回的组确实是你想要的。

那你为什么会遇到异常?我不知道。我很想知道完整的异常细节。那里可能会有一个十六进制数字。

但我认为这并不重要。只需准确匹配名称即可解决所有这些问题:

searcher.Filter = "(&(objectClass=group)(cn=SGNAME))";

向群组添加成员

我的猜测是您的member 变量不是正确的distinguishedName。不要尝试从Path 中解析DN,只需在搜索结果中询问distinguishedName。例如:

searcher.Filter = "(SAMAccountName=" + UserAlias + ")";
searcher.PropertiesToLoad.Add("distinguishedName");

SearchResult userALias = searcher.FindOne();

DirectoryEntry ent = securityGroup.GetDirectoryEntry();              

string member = (string) userALias.Properties["distinguishedName"][0];

ent.Properties["member"].Add(member);

ent.CommitChanges();
ent.Close();

更新:您也无法通过全局目录进行更新。你必须使用LDAP://:

string strActiveDirectoryPath = "LDAP://domain.com";

或者,如果您确实需要搜索 GC(如果您的林中有多个域),那么您必须在为组创建 DirectoryEntry 时切换到 LDAP。

DirectoryEntry ent = new DirectoryEntry(securityGroup.Path.Replace("GC://", "LDAP://"));

【讨论】:

  • 感谢您的回复。您给出的建议是在找到安全组时工作的。但是现在我得到了例外。更新的问题有例外
  • ExtendedErrorMessage 说明了真正的问题。我已经更新了我的答案。你只需要使用LDAP:// 而不是GC://
  • 如果您确实需要在 GC 上执行搜索,我添加了另一个选项。
  • 是的,需要替换逻辑。但我现在收到错误:访问被拒绝。不知道如何检查帐户权限。谢谢你的帮助。欣赏它
  • 如果您没有将凭据传递给组的DirectoryEntry,那么它将使用运行应用程序所使用的任何凭据。因此,您需要使用有权修改组的帐户运行应用程序,或者将凭据传递给具有权限的帐户DirectoryEntry
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多