我在使用内部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
答案 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>