研究:
指向 Microsoft End Point 更新的类似问题是罪魁祸首
上面的链接最适合我的问题,我还查看了 Stack Overflow 在创建这篇文章时列出的每个类似问题,只有上面引用的问题适合我的问题。
背景:
UserPrincipal.GetAuthorizationGroups
两年半以来,我一直在使用C#.NET 4.0 Web 表单站点中的 Server 2008 R2 上运行 IIS 7.5 的特定页面访问权限。2013 年 5 月 15 日,我们删除了运行 Server 2008(不是 r2)的主域控制器,并将其替换为 Server 2012 域控制器。第二天,我们开始收到下面列出的异常。
我使用 Principal Context 进行表单身份验证。用户名/密码握手成功并且 auth cookie 设置正确,但随后的 Principal Context 调用也会UserPrincipal.GetAuthorizationGroups
间歇性地失败。我们已经解决了一些出现在 Server 2012 域控制器中的 BPA 问题,但这还没有解决问题。我还建立了一个运行在两个独立服务器上的 cron。尽管它们运行相同的代码库,但两台服务器将在不同时间在 Group SID 解析中失败。(开发环境和生产环境)。
该问题会在 Web 服务器重新启动后暂时自行解决,并且在开发服务器上它会在 12 小时无法运行后自行解决。生产服务器通常会停止正常运行,直到重新启动而不自行解决。
在这一点上,我正在尝试改进针对网络中特定域控制器以及新 DC 的 cron,并使用当前无法产生更有针对性的异常时间的标准 LDAP 查询。到目前为止,我们在一台 Web 服务器上发现它失败的日子没有规律,但它会在大约 12 小时内恢复。最新结果显示,Group 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 Server 2008(不是 r2)并实施新的 Server 2012 DC 会导致UserPrincipal.GetAuthorizationGroups
失败并出现 1301 SID 解析错误?关于消除可能原因的想法也将不胜感激。
免责声明:
这是我在 Stack Overflow 上的第一篇文章,我经常在这里研究,但直到现在才参与讨论。如果我应该在其他地方发布,请原谅我,并在发布之前随时指出更好的步骤。
2013 年 6 月 13 日更新:
在 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;
}