从Web服务调用时,Domain.GetDomain(...)失败

时间:2009-12-29 19:11:42

标签: c# active-directory dns

我在从Web服务调用的类中有以下代码:

NetworkCredential credentials = new NetworkCredential("user", "password");

connection = new LdapConnection("domain");
connection.Bind(credentials);

DirectoryContext directoryContext = 
    new DirectoryContext(DirectoryContextType.Domain, "domain");

//  This call returns a domain object with unreadable properties
Domain domain = Domain.GetDomain(directoryContext);

如果我直接实例化该类,一切都很好,我有一个可以使用的有效域对象。如果我通过Web服务,则会创建域对象,但大多数属性会抛出异常,例如:

'domain.Children' threw an exception of type ActiveDirectoryOperationException

我启用了模拟,并且在调用Web服务之前显式设置了凭据。检查Web服务端的Thread.CurrentPrincipal.Identity.Name会显示我明确设置的凭据的用户名。

如果我查看Request.LogonUserIdentity,我有以下属性:

Name:  "domain\\username"  (is correct)
ImpersonationLevel:  Impersonation
IsAnonymous:  false
IsAuthenticated:  true
AuthenticationType:  NTLM

禁用匿名访问(启用它没有区别),并且都检查了“基本身份验证”和“集成Windows身份验证”。 Web服务在我的开发框上的IIS 5.1下运行。

调用Web服务的代码,导致对Domain.GetDomain()的调用失败:

MyServiceProxy proxy = new MyServiceProxy ();

CredentialCache credCache = new CredentialCache();
NetworkCredential netCred = new NetworkCredential(user, password, domain);
credCache.Add(new Uri(proxy.Url), "Ntlm", netCred);
proxy.Credentials = credCache;

proxy.MethodCall();

直接调用并成功的代码:

MyService myService = new MyService();
myService.MethodCall();

在Web服务的上下文中,为什么调用Active Directory的任何想法都会失败?而且,调用本身并没有失败...它返回一个具有不可读属性的域对象。

提前致谢!

2 个答案:

答案 0 :(得分:0)

当你这样做......

NetworkCredential credentials = new NetworkCredential("user", "password"); 

connection = new LdapConnection("domain"); 
connection.Bind(credentials); 

DirectoryContext directoryContext =  
    new DirectoryContext(DirectoryContextType.Domain, "domain"); 

//  This call returns a domain object with unreadable properties 
Domain domain = Domain.GetDomain(directoryContext);

...实际上,您只需使用特定的NetworkCredentials创建(System.DirectoryServices.Protocols).LdapConnection,然后根据该证书验证您的“用户”和“密码”凭据。但是你不再使用连接对象了;相反,你创建一个新的完全不相关的(System.DirectoryServices.ActiveDirectory).DirectoryContext-object。

因为您没有使用构造函数,而您明确指定用户名和密码,DirectoryContext对象将获得using the credentials of the user running the Application Pool(在IIS 6 +中,在IIS 5.1中,应用程序将在内存服务时使用我是对的,永远是本地系统帐户 - IUSR_XXX - 由于它不是域帐户,因此无法访问Active Directory。

在IIS环境中运行代码时使用的不同凭据与仅使用控制台应用程序进行测试(以登录/交互式用户身份运行代码)是导致问题的常见原因编程目录服务。

尝试使用构造函数where you specify a username and password for the DirectoryContext-object

就假冒而言,使用此代码段可能会有更好的运气......

System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext = 
    ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();

//Insert your code that runs under the security context of the authenticating user here.

impersonationContext.Undo();

......取自KB306158: How to implement impersonation in an ASP.NET application

答案 1 :(得分:0)

最后,我将其转换为IIS中托管的WCF服务,并且模拟很好。我很想知道问题是什么,但我必须继续前进,无论如何,WCF服务是一个更好的解决方案。谢谢你的帮助!