Dominio.GetDomain (...) falha quando chamado de um serviço web

tenho o seguinte código numa classe chamada a partir de um serviço 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);

Se eu instanciar a classe directamente, tudo ESTÁ BEM, tenho um objecto de domínio válido com o qual posso trabalhar. Se eu passar pelo serviço web, o objeto de domínio é criado, mas a maioria das propriedades lançar exceções, por exemplo:

'domain.Children' threw an exception of type ActiveDirectoryOperationException
Tenho a imitação activada e estou a definir explicitamente as credenciais antes de ligar para o serviço web. Examinando Thread.CurrentPrincipal.Identity.Name no lado do serviço web mostra o nome de utilizador das credenciais que defini explicitamente.

se olhar para Request.LogonUserIdentity, tenho as seguintes propriedades:

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

o acesso anónimo está desactivado (permitindo que não faça diferença), e a 'Autenticação Básica' e a 'autenticação integrada do Windows' estão ambas verificadas. O serviço web está a funcionar com o IIS 5.1 na minha caixa de desenvolvimento.

o código que chama o serviço web, resultando numa chamada falhada para domínio.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();

o código que chama directamente e sucesso:

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

alguma ideia por que razão as chamadas para Active Directory falhariam quando feitas no contexto de um serviço web? E mais uma vez, a chamada não falha por si só... devolve um objecto de domínio com propriedades ilegíveis.

Obrigado antecipadamente!

Author: James King, 2009-12-29

2 answers

Quando o fizeres...
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);

...na verdade, estás apenas a criar um sistema.Directores de serviços.Protocolo).LdapConnection with specific NetworkCredentials and you validate your " user "and" password " credentials against that. Mas então você não usa mais o objeto Conexão-objeto; em vez disso, você cria um novo totalmente independente (sistema.Directores de serviços.ActiveDirectory).DirectoryContext-object.

E porque não estás a usar um construtor onde estás explicitamente a especificar um nome de utilizador e uma palavra-passe a DirectoryContext-objeto receberá usando as credenciais do usuário que está executando o Pool de aplicativos (no IIS 6+, no IIS 5.1 a aplicação, se a memória não me serve direito, sempre de ser um/a conta sistema local - IUSR_XXX - que não será capaz de acessar o Active Directory, porque não é uma conta de domínio).

As diferentes credenciais que são usadas quando você está executando o seu código em um ambiente IIS versus apenas testar usando uma aplicação de console (onde você está executando código como o usuário logado/interativo) é uma causa comum de problemas nos Serviços de diretórios de programação.

Tente usar o construtor onde indica um nome de utilizador e uma senha para o DirectoryContext-object .

No que diz respeito à imitação, podes ter mais sorte se usares este excerto de código...
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();

...retirado de KB306158: como implementar a personificação num ASP.NET application .

 0
Author: Per Noalt, 2009-12-29 23:40:20
No final, converti isto num serviço WCF hospedado no IIS, e a imitação está boa. Eu adoraria saber qual era o problema, mas eu tive que seguir em frente, e um serviço WCF é uma solução melhor no geral, de qualquer maneira. Obrigado pela ajuda, no entanto!
 0
Author: James King, 2010-08-10 16:34:44