Ser*_*eit 22 c# directoryservices active-directory .net-3.5
我有一个使用ActiveDirecotry授权的应用程序,并且已经确定它需要支持嵌套的AD组,例如:
MAIN_AD_GROUP
|
|-> SUB_GROUP
|
|-> User
Run Code Online (Sandbox Code Playgroud)
所以,用户不是直接成员MAIN_AD_GROUP.我希望能够递归地查找用户,搜索嵌套的组MAIN_AD_GROUP.
主要问题是我使用的是.NET 3.5,并且.NET 3.5中存在一个错误System.DirectoryServices.AccountManagement,该方法UserPrincipal.IsMemberOf() 不适用于拥有超过1500个用户的组.所以我不能使用UserPrincipal.IsMemberOf()和不,我也无法切换到.NET 4.
我用以下函数解决了这个最后一个问题:
private bool IsMember(Principal userPrincipal, Principal groupPrincipal)
{
using (var groups = userPrincipal.GetGroups())
{
var isMember = groups.Any(g =>
g.DistinguishedName == groupPrincipal.DistinguishedName);
return isMember;
}
}
Run Code Online (Sandbox Code Playgroud)
但userPrincipal.GetGroups()只返回用户是其直接成员的组.
如何让它与嵌套组一起使用?
Tim*_*wis 33
此错误在Microsoft Connect中报告,以及通过手动迭代PrincipalSearchResult<Principal>返回的对象,捕获此异常并继续执行以下代码解决此问题的以下代码:
PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();
var iterGroup = groups.GetEnumerator();
using (iterGroup)
{
while (iterGroup.MoveNext())
{
try
{
Principal p = iterGroup.Current;
Console.WriteLine(p.Name);
}
catch (NoMatchingPrincipalException pex)
{
continue;
}
}
}
Run Code Online (Sandbox Code Playgroud)
此处找到的另一个解决方法是避免使用AccountManagement该类,System.DirectoryServices而是使用API:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
namespace GetGroupsForADUser
{
class Program
{
static void Main(string[] args)
{
String username = "Gabriel";
List<string> userNestedMembership = new List<string>();
DirectoryEntry domainConnection = new DirectoryEntry(); // Use this to query the default domain
//DirectoryEntry domainConnection = new DirectoryEntry("LDAP://example.com", "username", "password"); // Use this to query a remote domain
DirectorySearcher samSearcher = new DirectorySearcher();
samSearcher.SearchRoot = domainConnection;
samSearcher.Filter = "(samAccountName=" + username + ")";
samSearcher.PropertiesToLoad.Add("displayName");
SearchResult samResult = samSearcher.FindOne();
if (samResult != null)
{
DirectoryEntry theUser = samResult.GetDirectoryEntry();
theUser.RefreshCache(new string[] { "tokenGroups" });
foreach (byte[] resultBytes in theUser.Properties["tokenGroups"])
{
System.Security.Principal.SecurityIdentifier mySID = new System.Security.Principal.SecurityIdentifier(resultBytes, 0);
DirectorySearcher sidSearcher = new DirectorySearcher();
sidSearcher.SearchRoot = domainConnection;
sidSearcher.Filter = "(objectSid=" + mySID.Value + ")";
sidSearcher.PropertiesToLoad.Add("distinguishedName");
SearchResult sidResult = sidSearcher.FindOne();
if (sidResult != null)
{
userNestedMembership.Add((string)sidResult.Properties["distinguishedName"][0]);
}
}
foreach (string myEntry in userNestedMembership)
{
Console.WriteLine(myEntry);
}
}
else
{
Console.WriteLine("The user doesn't exist");
}
Console.ReadKey();
}
}
}
Run Code Online (Sandbox Code Playgroud)
mar*_*c_s 13
UserPrincipal.GetAuthorizationGroups()改为使用- 来自其MSDN文档:
此方法以递归方式搜索所有组,并返回用户所属的组.返回的集合还可以包括系统将用户视为授权目的的其他组.
此方法返回的组可能包括来自与主体不同的范围和存储的组.例如,如果主体是AD DS对象,其DN为"CN = SpecialGroups,DC = Fabrikam,DC = com,则返回的集合可以包含属于"CN = NormalGroups,DC = Fabrikam,DC =的组COM.
我知道这是一个旧帖子,但它是谷歌的最佳结果,所以如果这有助于任何人,这就是我提出的使用AccountManagement的东西,但使这个特定的查询更容易.
public static class AccountManagementExtensions
{
public static bool IsNestedMemberOf(this Principal principal, GroupPrincipal group)
{
// LDAP Query for memberOf Nested
var filter = String.Format("(&(sAMAccountName={0})(memberOf:1.2.840.113556.1.4.1941:={1}))",
principal.SamAccountName,
group.DistinguishedName
);
var searcher = new DirectorySearcher(filter);
var result = searcher.FindOne();
return result != null;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
29010 次 |
| 最近记录: |