在ASP.NET webapp中,FindByIdentity因PricipalOperationException而失败

时间:2009-12-08 00:23:24

标签: c# asp.net visual-studio active-directory

我在使用内部Web应用程序中的System.DirectoryServices.AccountManagement时遇到了一个问题。错误不是很具描述性,但这是正在发生的事情:

当我尝试验证AD中是否存在提供的用户ID时,我使用以下代码进行验证:

private bool IsWindowsIDValid(string strWindowsID) 
{ 
var context = new PrincipalContext(ContextType.Domain, "DOMAINSERVER", "DC=DOMAINNAME,DC=net"); 
var userPrincipal = UserPrincipal.FindByIdentity(context, strWindowsID); 
return (userPrincipal != null); 
} 

但是,在调用FindByIdentity的第二行抛出异常。以下是例外情况:

消息: “发生了操作错误。”

堆栈追踪:

at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInit() 在System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit() 在System.DirectoryServices.AccountManagement.PrincipalContext.Initialize() 在System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx() at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context,Type principalType,Nullable`1 identityType,String identityValue,DateTime refDate) 在System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context,Type principalType,String identityValue) 在System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context,String identityValue) 在*****。IsWindowsIDValid(String strWindowsID)在*****。ascx.cs:第193行

如果我尝试检查PrincipalContext的ConnectedServer属性,也会发生同样的错误。但是,我可以尝试根据上下文验证凭据(使用context.ValidateCredentials()),它将通过正常。

有关可能发生的事情的任何想法?我可以在我的机器上的独立控制台脚本中运行此代码 - 当我尝试调试webapp时,这发生在VisualStudio内部的本地开发环境中。这可能是权限问题还是其他问题?我在这一点上很丢失。

我感谢任何帮助!

-Patrick

2 个答案:

答案 0 :(得分:5)

一个老问题,但我有同样的错误。对我来说,问题是PrincipalContext在其构造函数中没有用户名和密码时无效...每当我调用UserPrincipal的任何方法或属性时,我都会得到完全相同的错误消息(或关于那个问题PrincipalContext

如果您指定对您指定的容器具有Active Directory权限的域用户的用户名和密码,则对FindByIdentity的调用应该会成功:

var context = new PrincipalContext(ContextType.Domain, "DOMAINSERVER",
                                   "DC=DOMAINNAME,DC=net", userName, pw); 
var userPrincipal = UserPrincipal.FindByIdentity(context, strWindowsID); 

对我来说,这不是一个解决方案,因为我不会有这两个参数。但这就是为什么你得到了你得到的错误。

根据微软的帮助,按照你的方式进行操作应该在调用进程的凭据下运行......但无论我在哪个运行(并且我已经验证了模拟),都会调用UserPrincipal没有在PrincipalContext上指定用户名和密码的对象将无效。

希望迟到有帮助, 詹姆斯

答案 1 :(得分:0)

对旧问题的另一个迟来的答案但是,这篇文章帮我解决了我的问题:http://support.microsoft.com/kb/329986

我得到的“操作错误”类似于这篇文章中的那个。

线索是建议在您的网络应用程序之外测试它。所以我创建了一个控制台应用程序,添加了对System.DirectoryServices.AccountManagement的引用,并输入了以下代码:

private static void Main(string[] args)
    {

        var adGroups = new List<string>();

        using (var principalContext = new PrincipalContext(ContextType.Domain))
        {
            using (var user = UserPrincipal.FindByIdentity(principalContext, @"MYDOMAIN\MYUSERNAME"))
            {
                if (user == null) return;

                var groups = user.GetAuthorizationGroups();
                adGroups.AddRange(from @group in groups
                                  where @group.Name.ToUpper().Contains("SOME-STRING-COMMON-TO-ALL-THE-AD-GROUPS-PERTINENT-TO-MY-MVC-APP")
                                  select @group.Name);
            }
        }
    }

这很有效,所以我确信我的问题是MS文章中描述的“双跳”问题。

解决方案是确保在我的web.config文件中启用了模拟。 (这是一个内部网应用程序,所以我打开了Windows身份验证模式,并启用了模拟;这解决了它。)

<system.web>
    <httpRuntime targetFramework="4.5" />
    <compilation debug="true" targetFramework="4.5" />
    <authentication mode="Windows" />
    <identity impersonate="true" />
    <authorization>
            <deny users="?" />
    </authorization>