【问题标题】:Why does DirectoryServicesCOMException occur querying Active Directory from a machine other than the web server?为什么从 Web 服务器以外的机器查询 Active Directory 时会发生 DirectoryServicesCOMException?
【发布时间】:2011-10-14 22:46:32
【问题描述】:

当请求来自 Web 服务器时,我在 IIS 7.5 上运行的 ASP.NET WebForms 应用程序运行良好,但当同一域用户从域中的任何其他计算机请求同一页面时,会引发以下错误:

类型:System.DirectoryServices.AccountManagement.PrincipalOperationException

MSG:发生操作错误。

在 System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInit() 在 System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit() 在 System.DirectoryServices.AccountManagement.PrincipalContext.Initialize() 在 System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx() 在 System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext 上下文,类型 principalType,Nullable`1 identityType,字符串 identityValue,DateTime refDate) 在 System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext 上下文,类型 principalType,字符串 identityValue) 在 System.DirectoryServices.AccountManagement.GroupPrincipal.FindByIdentity(PrincipalContext 上下文,字符串 identityValue) 在 c:\Users\David\Documents\VsProjects\CeoTrunk\Ceoimage.Basecamp\Basecamp\ActiveDirectory\SidSource.cs:line 115 中的 Ceoimage.Basecamp.ActiveDirectory.SidSource._TryGetGroupPrincipal(PrincipalContext context, String groupName)

-- 内部异常--

类型:System.DirectoryServices.DirectoryServicesCOMException

MSG:发生操作错误。

在 System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) 在 System.DirectoryServices.DirectoryEntry.Bind() 在 System.DirectoryServices.DirectoryEntry.get_SchemaEntry() 在 System.DirectoryServices.AccountManagement.ADStoreCtx.IsContainer(DirectoryEntry de) 在 System.DirectoryServices.AccountManagement.ADStoreCtx..ctor(DirectoryEntry ctxBase,布尔 ownCtxBase,字符串用户名,字符串密码,ContextOptions 选项) 在 System.DirectoryServices.AccountManagement.PrincipalContext.CreateContextFromDirectoryEntry(DirectoryEntry 条目) 在 System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInit()

应用程序的 web.config 文件指定 <authentication mode="Windows"><identity impersonate="true" />,但不使用成员资格提供程序。在 IIS 中,应用程序池以域用户身份运行,并且应用程序的身份验证已禁用除 ASP.NET 模拟(设置为已验证用户)和 Windows 身份验证之外的所有内容。

导致错误的代码只是尝试获取组的 SID 以验证用户应该访问应用程序:

public string GetGroupSid()
{
    using (var context = new PrincipalContext("Domain", "Test", "CN=Users,DC=Test,DC=local", ContextOptions.Negotiate))
    {
        var group = _TryGetGroupPrincipal(context, "AppGroup");
        return group.Sid.Value;
    }
}
private static GroupPrincipal _TryGetGroupPrincipal(PrincipalContext context, string groupName)
{
    try
    {
        return GroupPrincipal.FindByIdentity(context, groupName);
    }
    catch (Exception e)
    {
        throw _GetUnableToFindGroupException(e, groupName);
    }
}

正如我之前所说,如果请求来自 Web 服务器,则应用程序可以正常工作,但当同一个域用户从域中的任何其他计算机请求同一页面时,就会引发此错误。我知道enabling Kerberos,但您可以看到我的代码指定了ContextOptions.Negotiate。我不是这方面的专家,但我很困惑。

【问题讨论】:

  • 你还没有尝试过使用更原始的 AD 库,是吗?这不能回答您的问题,但我在使用 System.DirectoryServices.AccountManagement 命名空间时遇到了问题,该命名空间可以与 System.DirectoryServices.ActiveDirectory 命名空间一起使用。去图吧。
  • 这就是我开始的方式,但这种方式似乎更干净。我更倾向于认为这是一个配置问题,即模拟用户在 ASP.NET 上下文中可以做什么和不可以做什么。您能否指出任何使用“更原始的 AD 库”的示例,这些示例允许 ASP.NET 获取特定 AD 组的 SID?

标签: c# asp.net active-directory windows-authentication


【解决方案1】:

Configuring the web server for delegation 允许我的 Web 应用无错误地查询 AD 组的 SID,并且无需更改任何代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多