UserPrincipals.GetAuthorizationGroups枚举组时发生错误(1301)。 该组的SID无法解决

背景:

我一直在使用UserPrincipal.GetAuthorizationGroups一段时间来检查2个不同应用程序的权限。 他们已经好几年了。 最近一些用户已经收到标题中提到的错误( System.DirectoryServices.AccountManagement.PrincipalOperationException ),而其他用户则没有。 我怀疑它可能与在Windows Server 2012上运行的新域控制器有关,因为问题在添加后的第二天就开始了。 完整错误如下:

例外:

System.DirectoryServices.AccountManagement.PrincipalOperationException:枚举组时发生错误(1301)。 该组的SID无法解决。

在System.DirectoryServices.AccountManagement.SidList.TranslateSids(String target,IntPtr [] pSids)at System.DirectoryServices.AccountManagement.SidList..ctor(SID_AND_ATTR [] sidAndAttr)

at System.DirectoryServices.AccountManagement.AuthZSet..ctor(Byte [] userSid,NetCred credentials,ContextOptions contextOptions,String flatUserAuthority,StoreCtx userStoreCtx,Object userCtxBase)

在System.DirectoryServices.AccountManagement.ADStoreCtx.GetGroupsMemberOfAZ … p)

在System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroups

题:

我该如何解决?

我找到了使用DirectorySearcher的替代方法:

 var allDomains = Forest.GetCurrentForest().Domains.Cast(); var allSearcher = allDomains.Select(domain => { DirectorySearcher searcher = new DirectorySearcher( new DirectoryEntry("LDAP://" + domain.Name)); searcher.Filter = String.Format( "(&(&(objectCategory=person)(objectClass=user)(userPrincipalName=*{0}*)))", "Current User Login Name"); return searcher; } ); var directoryEntriesFound = allSearcher.SelectMany(searcher => searcher.FindAll() .Cast() .Select(result => result.GetDirectoryEntry())); var memberOf = directoryEntriesFound.Select(entry => { using (entry) { return new { Name = entry.Name, GroupName = ((object[])entry.Properties["MemberOf"].Value) .Select(obj => obj.ToString()) }; } } ); foreach (var user in memberOf) { foreach (var groupName in user.GroupName) { if (groupName.Contains("Group to Find")) { // Do something if the user is in that group } } } 

检查此答案: UserPrincipals.GetAuthorizationGroups枚举组时发生错误(1301)。 升级到Server 2012域控制器后

MS修复http://support.microsoft.com/kb/2830145

我有同样的例外。 如果有人不想使用“LDAP”,请使用此代码。 因为我有嵌套组,我使用了GetMembers(true),它的时间比GetMembers()稍长。

或者从这里下载修复程序,如@Tilo: http : //support.microsoft.com/kb/2830145

 public bool IsMember(UserPrincipal user, string groupName) { try { var context = new PrincipalContext(ContextType.Domain, Environment.UserDomainName); var group = GroupPrincipal.FindByIdentity(context, groupName); if (group == null) { //Not exist } else { if (group.GetMembers(true).Any(member => user.SamAccountName.ToLower() == member.SamAccountName.ToLower())) { return true; } } } catch (Exception exception) { //exception } return false; }