研究:
类似的问题指出微软的端点更新是罪魁祸首。
上面的链接是最适合我的问题,我也看过每一个类似的问题所列出的堆栈溢出在创建这篇文章,只有上述参考问题适合我的问题。
背景:
两年半来,我一直使用UserPrincipal.GetAuthorizationGroups作为特定页面访问权限,在服务器2008 R2上运行IIS7.5Web窗体站点中的IIS7.5。2013年5月15日,我们删除了运行服务器2008 (而不是r2)的主域控制器,并将其替换为Server 2012域控制器。第二天,我们开始收到下面列出的异常。
我使用主体上下文进行窗体身份验证。用户名/传递握手成功,auth被正确设置,但随后也调用UserPrincipal.GetAuthorizationGroups的主体上下文调用间歇性失败。我们已经解决了服务器2012域控制器中出现的一些BPA问题,但这还没有解决这个问题。我还建立了一个运行在两个独立服务器上的cron。虽然这两台服务器运行的代码库相同,但它们在不同的时间以Group解析失败。(开发环境和生产环境)。
这个问题在web服务器重新启动时临时解决,在dev服务器上,它将在12小时不工作后自行解决。生产服务器通常会停止正常运行,直到重新启动,而不自行解决。
此时,我试图细化针对网络中特定域控制器的cron,以及新的DC,并使用标准LDAP查询,该查询目前无法产生更多的目标异常时间。到目前为止,我们已经在一台web服务器上发现,在失败的日子里没有模式,但它将在大约12小时内恢复。最新结果显示,SID的解析度在上午8点到晚上8点之间失效,然后恢复,几天后,它将在晚上8点失效,在早上8点恢复,然后再运行12小时,然后再次失败。我们希望看看这是一个特定的服务器通信问题,还是看看它是否是整个域控制器集。
异常:
Exception information:
Exception type: PrincipalOperationException
Exception message: An error (1301) occurred while enumerating the groups.
The group's SID could not be resolved.
at 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)
at System.DirectoryServices.AccountManagement.ADStoreCtx.GetGroupsMemberOfAZ(Principal p)
at System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroups()问题:
鉴于上述信息,有没有人知道为什么关闭Windows 2008 (而不是r2)并实现新的Server2012DC会导致UserPrincipal.GetAuthorizationGroups在1301SID解析错误时失败?关于消除可能的原因的想法也将受到赞赏。
免责声明:
这是我第一次发表堆栈溢出,我经常在这里研究,但直到现在还没有参加讨论。请原谅我,如果我应该张贴到其他地方,并自由地指出更好的步骤,然后再发帖。
更新13-6月-2013年6月:
6月12日,我讨论了不处置引起这一问题的物品的可能性。时间太短,无法确定调整后的代码是否解决了这一问题,但我将继续更新,因为我们正致力于解决这个问题,如果幸运的话,这里的人可能会伸出援手。
原始代码
public bool isGroupMember(string userName, ArrayList groupList)
{
bool valid = false;
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domain_server + ".domain.org:636", null, ContextOptions.Negotiate | ContextOptions.SecureSocketLayer);
// find the user in the identity store
UserPrincipal user =
UserPrincipal.FindByIdentity(
ctx,
userName);
// get the groups for the user principal and
// store the results in a PrincipalSearchResult object
PrincipalSearchResult<Principal> groups =
user.GetAuthorizationGroups();
// display the names of the groups to which the
// user belongs
foreach (Principal group in groups)
{
foreach (string groupName in groupList)
{
if (group.ToString() == groupName)
{
valid = true;
}
}
}
return valid;
}更新代码
public bool isGroupMember(string userName, ArrayList groupList, string domain_server)
{
bool valid = false;
try
{
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domain_server + ".domain.org:636", null, ContextOptions.Negotiate | ContextOptions.SecureSocketLayer))
{
// find the user in the identity store
UserPrincipal user =
UserPrincipal.FindByIdentity(
ctx,
userName);
try
{
// get the groups for the user principal and
// store the results in a PrincipalSearchResult object
using (PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups())
{
// display the names of the groups to which the
// user belongs
foreach (Principal group in groups)
{
foreach (string groupName in groupList)
{
if (group.ToString() == groupName)
{
valid = true;
}
}
group.Dispose();
}
}//end using-2
}
catch
{
log_gen("arbitrary info");
return false;
}
}//end using-1
}
catch
{
log_gen("arbitrary info");
return false;
}
return valid;
}发布于 2013-10-15 14:45:52
我刚刚遇到了同样的问题,我设法找到的信息可能会有帮助;如上所述,我们看到了域控制器正在运行Server 2012的问题--首先使用客户部署,然后在我们自己的网络上复制。
经过一些实验后,我们发现我们的代码在Server 2012上运行良好,但在客户端系统运行Server 2008时却命中了1301错误代码。关于正在发生的事情的关键信息在这里找到:
blog女士从德语翻译过来
下面的链接中提到的修补程序已经解决了我们测试系统上的问题。
SID S-1-18-1和SID S-1-18-2不能映射
希望这对某人有帮助!正如许多人所注意到的,这个方法调用看起来相当脆弱,在我们遇到其他问题之前,我们可能会考虑实现一些替代方法。
加里
发布于 2014-08-18 16:57:56
这是我的解决办法。它似乎一直运作得很好。因为这个问题发生在遍历集合时,我在迭代时使用了一种不同的方法,以便在不阻塞实际迭代的情况下处理异常:
private string[] GetUserRoles(string Username)
{
List<string> roles = new List<string>();
try
{
string domain = Username.Contains("\\") ? Username.Substring(0, Username.IndexOf("\\")) : string.Empty;
string username = Username.Contains("\\") ? Username.Substring(Username.LastIndexOf("\\") + 1) : Username;
if (!string.IsNullOrEmpty(domain) && !string.IsNullOrEmpty(username))
{
PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, domain);
UserPrincipal user = UserPrincipal.FindByIdentity(principalContext, username);
if (user != null)
{
PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();
int count = groups.Count();
for (int i = 0; i < count; i++)
{
IEnumerable<Principal> principalCollection = groups.Skip(i).Take(1);
Principal principal = null;
try
{
principal = principalCollection.FirstOrDefault();
}
catch (Exception e)
{
//Error handling...
//Known exception - sometimes AD can't query a particular group, requires server hotfix?
//http://support.microsoft.com/kb/2830145
}
if (principal!=null && principal is GroupPrincipal)
{
GroupPrincipal groupPrincipal = (GroupPrincipal)principal;
if (groupPrincipal != null && !string.IsNullOrEmpty(groupPrincipal.Name))
{
roles.Add(groupPrincipal.Name.Trim());
}
}
}
}
}
}
catch (Exception e)
{
//Error handling...
}
return roles.ToArray();
}发布于 2014-01-20 13:16:04
当我们的基础设施团队将2012年的域控制器( Domain )上线时,我们就经历了这个问题。我们也有2012年前的发展中国家到位,因此我们间歇性地经历了这个问题。我们想出了一个解决办法,我想要分享-它有两个部分。
首先,安装Gary提到的热修复。这将解决以下问题:
枚举组时发生错误(1301)。该小组的SID无法解决。
在安装了这个修补程序之后,我们以为我们已经免费回家了。然而,在安装之后,我们得到了一个不同的间歇错误。我们正在审讯的某些群体拥有一个空sAMAccountName属性。Active Directory中填充了实际的属性,但是API不正确地以空值返回该属性。我猜想这是中的一个bug,但我不知道更多。
幸运的是,我们能够通过切换到使用组Name属性而不是sAMAccountName属性来解决这个问题。这对我们有用。我认为,sAMAccountName实际上是不受欢迎的,并且只存在于向后兼容的原因。既然如此,这似乎是一个合理的改变。
我附上了我们的GetRolesForUser代码的精简版本,以演示所做的更改。
using (var context = new PrincipalContext(ContextType.Domain, _domainName))
{
try
{
var p = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username);
if (p == null) throw new NullReferenceException(string.Format("UserPrincipal.FindByIdentity returned null for user: {0}, this can indicate a problem with one or more of the AD controllers", username));
var groups = p.GetAuthorizationGroups();
var domain = username.Substring(0, username.IndexOf(@"\", StringComparison.InvariantCultureIgnoreCase)).ToLower();
foreach (GroupPrincipal group in groups)
{
if (!string.IsNullOrEmpty(group.Name))
{
var domainGroup = domain + @"\" + group.Name.ToLower();
if (_groupsToUse.Any(x => x.Equals(domainGroup, StringComparison.InvariantCultureIgnoreCase)))
{
// Go through each application role defined and check if the AD domain group is part of it
foreach (string role in roleKeys)
{
string[] roleMembers = new [] { "role1", "role2" };
foreach (string member in roleMembers)
{
// Check if the domain group is part of the role
if (member.ToLower().Contains(domainGroup))
{
// Cache the Application Role (NOT the AD role)
results.Add(role);
}
}
}
}
}
group.Dispose();
}
}
catch (Exception ex)
{
throw new ProviderException("Unable to query Active Directory.", ex);
}
}希望这能有所帮助。
https://stackoverflow.com/questions/17027781
复制相似问题