C# 为什么我们必须等待某个时间从UserPrincipal.GetAuthorizationGroups方法获取最新的组信息?

C# 为什么我们必须等待某个时间从UserPrincipal.GetAuthorizationGroups方法获取最新的组信息?,c#,.net,active-directory,C#,.net,Active Directory,我们有一个广告用户,比如说userA,它是GroupA,GroupB的成员 使用UserPrincipal.GetAuthorizationGroups方法可以给出这些组 然后我们将userA添加到另一个组,比如说GroupC 但在添加到新组并运行UserPrincipal.GetAuthorizationGroups方法之后,仍然显示GroupA、GroupB它不显示GroupC 如果我们有时等待(大约10分钟)或切换用户并再次登录,那么只有UserPrincipal.GetAuthoriza

我们有一个广告用户,比如说userA,它是GroupAGroupB的成员

使用UserPrincipal.GetAuthorizationGroups方法可以给出这些组

然后我们将userA添加到另一个组,比如说GroupC

但在添加到新组并运行UserPrincipal.GetAuthorizationGroups方法之后,仍然显示GroupA、GroupB它不显示GroupC

如果我们有时等待(大约10分钟)或切换用户并再次登录,那么只有UserPrincipal.GetAuthorizationGroups方法显示GroupC以及GroupA、GroupB

为什么我们必须等待或再次登录才能获取最新值?


对于UserPrincipal.GetGroups方法,我们不必等待或再次登录。我们使用的是UserPrincipal.GetAuthorizationGroups方法,因为我们还需要嵌套的组

似乎具体的实现不是100%可信的。用户组被缓存,而函数不考虑这一点

只需说一句,即使不是所有情况,它在大多数情况下都是有意义的。新的组在登录后应用,并且每次检索都查询广告,这似乎是一种过火的行为

有关更多信息和解决方案,请查看此处:

IEnumerable GetGroups(字符串samAccountName)
{
var userNestedMembership=新列表();
var domainConnection=new DirectoryEntry();
domainConnection.AuthenticationType=System.DirectoryServices.AuthenticationTypes.Secure;
var samSearcher=newdirectorysearcher();
samSearcher.SearchRoot=域连接;
samSearcher.Filter=“(samAccountName=“+samAccountName+”);
samSearcher.PropertiesToLoad.Add(“displayName”);
var samResult=samSearcher.FindOne();
if(samResult!=null)
{
var theUser=samResult.GetDirectoryEntry();
RefreshCache(新字符串[]{“tokenGroups”});
foreach(user.Properties[“令牌组”]中的字节[]结果字节)
{
var SID=新的SecurityIdentifier(结果字节,0);
var sidSearcher=newdirectorysearcher();
sidSearcher.SearchRoot=域连接;
sidSearcher.Filter=“(objectSid=“+SID.Value+””);
sidSearcher.PropertiesToLoad.Add(“名称”);
var sidResult=sidSearcher.FindOne();
if(sidResult!=null)
{
userNestedMembership.Add((字符串)sidResult.Properties[“name”][0]);
}
}
}
返回userNestedMembership;
}
IEnumerable<String> GetGroups( String samAccountName )
{
    var userNestedMembership = new List<string>();

    var domainConnection = new DirectoryEntry();
    domainConnection.AuthenticationType = System.DirectoryServices.AuthenticationTypes.Secure;

    var samSearcher = new DirectorySearcher();

    samSearcher.SearchRoot = domainConnection;
    samSearcher.Filter = "(samAccountName=" + samAccountName + ")";
    samSearcher.PropertiesToLoad.Add( "displayName" );

    var samResult = samSearcher.FindOne();

    if ( samResult != null )
    {
        var theUser = samResult.GetDirectoryEntry();
        theUser.RefreshCache( new string[] { "tokenGroups" } );

        foreach ( byte[] resultBytes in theUser.Properties[ "tokenGroups" ] )
        {
            var SID = new SecurityIdentifier( resultBytes, 0 );
            var sidSearcher = new DirectorySearcher();

            sidSearcher.SearchRoot = domainConnection;
            sidSearcher.Filter = "(objectSid=" + SID.Value + ")";
            sidSearcher.PropertiesToLoad.Add( "name" );

            var sidResult = sidSearcher.FindOne();
            if ( sidResult != null )
            {
                userNestedMembership.Add( ( string )sidResult.Properties[ "name" ][ 0 ] );
            }
        }
    }

    return userNestedMembership;
}