2

我有一个Web应用程序(.NET 3.5),它通过电子邮件向用户发送通知。为了做到这一点,我搜索Active Directory来查找每个人的电子邮件。如何使用登录人员的凭据来搜索Active Directory?

此刻,我硬编码自己的用户名和密码,像这样以搜索广告:

Dim entry As New DirectoryEntry("LDAP://companyad", "myUsername", "myPassword", AuthenticationTypes.Secure) 
    Dim srch As New DirectorySearcher(entry) 
    srch.Filter = [String].Format("(&(objectClass=person)(sAMAccountName={0}))", "someOtherUsername") 
    Dim result As SearchResult = srch.FindOne() 

现在,很明显,这不是很理想,我不希望这些证书硬编码。我的网络应用程序使用Windows身份验证。它还使用模拟(作为登录用户)来访问文件和SQL Server。是否还有一种方法让我“模仿”登录用户以搜索AD?

编辑1

我想我会更好地解释为什么我选择了这个答案。问题原来不是多跳问题或kerberos,因为它似乎已经正确设置了这些。

我最近更改了我的应用程序,只允许通过web.config设置访问某个组。我以前只允许访问自己。我设立了这个小组,并加入了它。然后我删除了硬编码的凭据,并尝试在没有重新启动计算机的情况下运行该应用程序。

根据我的网络管理员,我不会在该新组下登录,直到我重新启动我的计算机,我认为是什么导致我的问题。所以,Preet的答案实际上是最准确的,因为我需要将LDAP路径传递给DirectoryEntry。

EDIT 2

我还需要注册一个服务主体名称。

我跑了这一点:

setspn -A HTTP/[dns name of the site] [machine name] 

我的机器上。

感谢其他人的回答。

回答

0

Dim entry As New DirectoryEntry("LDAP://companyad") 

工作?

+0

不幸的是,没有。我得到这个异常:“Type:System.Runtime.InteropServices.COMException,mscorlib,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089 消息:发生操作错误。”有用,嗯? – Andrew 2010-03-04 05:55:58

+0

检查事件日志中的内容。 – 2010-03-04 06:19:58

0

为什么不为此创建一个新用户?只有搜索权限的用户。

+0

我想这个选项是我最后的选择。此外,所有密码每月都会重置是公司政策,这意味着我必须每月在应用中更改密码。 – Andrew 2010-03-04 06:03:46

+0

啊!!! :)即使我们有这个政策,但有特例的例外。 – Shoban 2010-03-04 06:19:52

+0

哈哈,是的,如果涉及到这一点,那么我希望我的老板能够灵活地适应它。 – Andrew 2010-03-04 06:22:45

0

我在我的web.config中设置了< identity impersonate =“true”/ >,并将以下代码添加到我的页面加载事件处理程序中。它运行良好。你确定你没有处理多跳的情况吗?在这种情况下,您的应用程序池帐户需要配置kerberos身份验证以支持多人场景中的模拟。更多关于这方面的信息是在这里:http://support.microsoft.com/kb/329986

Response.Write(User.Identity.Name); 
DirectoryEntry entry = new DirectoryEntry("LDAP://[mydomain.net]"); 
DirectorySearcher srch = new DirectorySearcher(entry); 
srch.Filter = string.Format("(&(objectClass=person)(sAMAccountName={0}))", "[user]"); 
SearchResult result = srch.FindOne(); 
Response.Write(result.Path); 
0

如果你想使用Windows用户帐户登录,作为对AD的凭证,你必须使用以下方法:

public bool IsExistingUser() { 
    DirectoryEntry de = new DirectoryEntry(Environment.UserDomainName) 
    DirectorySearcher ds = new DirectorySearcher(de) 
    ds.Filter = string.Format("((objectClass=user)(SAMAccountName={0}))", Environment.UserName) 

    try 
     SearchResult sr = ds.FindOne(); 
     if (sr != null && sr.DirectoryEntry.Name.Contains(Environment.UserName)) 
      return true; 
    catch (DirectoryServicesCOMException ex) 
    catch (COMException ex) 
     throw new Exception("Can't find logged in user in AD", ex); 

    return false; 
} 

假设这段代码编译并运行,它将验证您的域控制器是否知道现有的登录用户。

模仿不鼓励,因为它可以让你的网络上传输密码字符串。所以,尽量避免它。

编辑这里是一个非常有用的广告链接:Howto: (Almost) Everything In Active Directory via C#我觉得这篇文章真棒!

相关问题