C# 使用Sharepoint API获取AD域组的成员

C# 使用Sharepoint API获取AD域组的成员,c#,dns,sharepoint-2010,active-directory-group,C#,Dns,Sharepoint 2010,Active Directory Group,在我的Sharepoint代码中,我通过以下方式显示所有已定义用户的列表: foreach (SPUser user in SPContext.Current.Web.AllUsers) { ... } 最重要的是,我可以将域安全组添加到Sharepoint组(如访问者),从而一次添加多个用户(更简单的管理)。但是我的代码不会看到这些用户,至少在他们第一次登录之前(如果他们有足够的权限的话)。在这种情况下,我只能看到域安全组SPUser对象实例,其IsDomainGroup设置为tru

在我的Sharepoint代码中,我通过以下方式显示所有已定义用户的列表:

foreach (SPUser user in SPContext.Current.Web.AllUsers)
{
    ...
}
最重要的是,我可以将域安全组添加到Sharepoint组(如访问者),从而一次添加多个用户(更简单的管理)。但是我的代码不会看到这些用户,至少在他们第一次登录之前(如果他们有足够的权限的话)。在这种情况下,我只能看到域安全组
SPUser
对象实例,其
IsDomainGroup
设置为
true


是否可以通过Sharepoint获取域组成员而无需借助Active Directory查询(这是我宁愿避免的,因为您可能需要足够的权限来执行此类操作=更多管理:Sharepoint权限+广告权限).

您可以使用方法
SPUtility.GetPrincipalsInGroup
()

除了
字符串输入
(安全组的NT帐户名)之外,所有参数都是自解释的:

bool reachedMaxCount;
SPWeb web = SPContext.Current.Web;
int limit = 100;
string group = "Domain\\SecurityGroup";
SPPrincipalInfo[] users = SPUtility.GetPrincipalsInGroup(web, group, limit, out reachedMaxCount);
请注意,此方法不会解析嵌套的安全组。此外,执行用户需要在当前web上具有浏览用户信息权限(
SPBasePermissions.browseServerInfo

更新:

private void ResolveGroup(SPWeb w, string name, List<string> users)
{
    foreach (SPPrincipalInfo i in SPUtility.GetPrincipalsInGroup(w, name, 100, out b))
    {
        if (i.PrincipalType == SPPrincipalType.SecurityGroup)
        {
          ResolveGroup(w, i.LoginName, users);
        }
        else
        {
          users.Add(i.LoginName);
        }
    }
}

List<string> users = new List<string>();
foreach (SPUser user in SPContext.Current.Web.AllUsers)
{
  if (user.IsDomainGroup)
    {
      ResolveGroup(SPContext.Current.Web, user.LoginName, users);
    }
    else
    {
      users.Add(user.LoginName);
    }
}
private void解析组(SPW、字符串名称、列表用户)
{
foreach(SPPrincipalInfo i in SPUtility.GetPrincipalsInGroup(w,name,100,out b))
{
if(i.PrincipalType==SPPrincipalType.SecurityGroup)
{
ResolveGroup(w,i.LoginName,用户);
}
其他的
{
users.Add(i.LoginName);
}
}
}
列表用户=新列表();
foreach(SPContext.Current.Web.alluser中的SPUser用户)
{
if(user.IsDomainGroup)
{
ResolveGroup(SPContext.Current.Web、user.LoginName、users);
}
其他的
{
users.Add(user.LoginName);
}
}
编辑:

private void ResolveGroup(SPWeb w, string name, List<string> users)
{
    foreach (SPPrincipalInfo i in SPUtility.GetPrincipalsInGroup(w, name, 100, out b))
    {
        if (i.PrincipalType == SPPrincipalType.SecurityGroup)
        {
          ResolveGroup(w, i.LoginName, users);
        }
        else
        {
          users.Add(i.LoginName);
        }
    }
}

List<string> users = new List<string>();
foreach (SPUser user in SPContext.Current.Web.AllUsers)
{
  if (user.IsDomainGroup)
    {
      ResolveGroup(SPContext.Current.Web, user.LoginName, users);
    }
    else
    {
      users.Add(user.LoginName);
    }
}
[…]求助于Active Directory查询(这是我宁愿避免的,因为您可能需要足够的权限来执行此类操作[…]

当然,这是事实,但SharePoint也必须查找广告。这就是为什么应用程序池服务帐户必须具有对广告的读取权限。
换句话说,如果您运行的代码还原为进程帐户,您应该可以安全地对AD执行查询。

我建议您直接查询Active Directory。您正在花费大量精力尝试让SharePoint为您呼叫AD。具有域用户访问权限的每个帐户都应该能够查询AD您在SharePoint中嵌套的广告组。我只需转到源


这样,您就不必担心浏览用户权限或其他任何问题。我认为,尝试通过SharePoint代理这一问题只会让您的生活更加困难。

好。但它是否会彻底消除嵌套组?因为内部成员也是主体。不,嵌套组不会得到解决。如果性能不相关,则递归调用使用这个方法应该没什么大不了的。嵌套组也会作为主体信息返回。好吧,如果我枚举
SPContext.Current.Web.alluser
并访问域组,我可以使用这个名称来使用
getprincipalssingroup
?我还没有测试,所以我只是问一个额外的问题。是的,使用
SPUser.LoginName
用于
输入
参数。如果认为您的代码exmaple.Line“If(i.Type==SPPrincipalType.SecurityGroup)”中有错误。它应该是“i.PrincipalType”而不是“i.Type”(至少在SharePoint 2010中)。想添加一些c#代码吗?我知道我可以在网上找到它,但是用一些代码支持你的答案会更好。对不起,我还是新来的。看起来你可以轻松修改它,以实现解决问题的可靠解决方案。