C#查询Active Directory

时间:2014-04-11 04:05:05

标签: c# c#-4.0 active-directory ldap

我正在开发一个Intranet Web应用程序,我正在使用System.DirectoryServices.AccountManagement来查询当前用户的Windows标识的Active Directory。在我的开发机器上,查询返回一个填充了用户信息的UserPrincipal。我的计算机上本地IIS的默认网站下的应用程序目录启用了Windows身份验证和模拟。但是,当应用程序发布到我们的托管IIS时,将返回Principal但没有用户信息。有谁知道为什么?服务器管理员说我必须使用服务帐户和密码连接到AD服务器来进行查询。如果这是真的,那么从我的本地机器查询应该也没有用。这是对的吗?

public class LDAP_Helper
{
    public string NetworkName { get; private set; }
    public string LastName { get; private set; }
    public string FirstName { get; private set; }
    public string MiddleName { get; private set; }
    public string Email { get; private set; }
    public string VoicePhone { get; private set; }

    public LDAP_Helper()
    {
        using (var context = new System.DirectoryServices.AccountManagement.PrincipalContext(
            System.DirectoryServices.AccountManagement.ContextType.Domain))
        {
            try
            {
                string currentUser = HttpContext.Current.User.Identity.Name;
                var principal = System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(context, currentUser);

                NetworkName = principal.SamAccountName;
                LastName = principal.Surname;
                FirstName = principal.GivenName;
                MiddleName = principal.MiddleName;
                Email = principal.EmailAddress;
                VoicePhone = principal.VoiceTelephoneNumber;
            }
            catch { }

        }

        return;
    }

Web.config settig:

    <identity impersonate="true" />

IIS7 Authentication IIS7 App Pool

3 个答案:

答案 0 :(得分:1)

首先,你捕获所有异常并对它们不采取任何措施,因此这并不好。如果您确实处理了异常,那么您可能会首先获得一个PrincipalOperationException,告诉您没有找到该名称的用户,然后是6 NullReferenceExceptions,因为您的主要变量是Nothing。我不是C#家伙,但这个VB位不应该太难翻译。您还应在创建上下文时指定域,以避免在具有多个域控制器的网络上出现问题。您确实需要具有查询Active Directory服务器的权限,但绝不是必须是服务帐户。只是具有适当组成员身份的常规帐户。

 Public Function FindUserPrincipal(ByVal userName As String) As UserPrincipal
    Try
        Return UserPrincipal.FindByIdentity(New PrincipalContext(ContextType.Domain, "mydomain"), IdentityType.SamAccountName, userName)
    Catch ex As PrincipalOperationException
        Return Nothing
    End Try
End Function

您还可以在创建上下文时以LDAP专有名称的形式指定搜索根,从而将搜索范围缩小到服务器上的单个组织单位,从而显着提高大型网络的性能。

Private Function GetPrincipalContext(ByVal domain As String, ByVal ldapDn As String) As PrincipalContext
    Try
        If String.IsNullOrWhiteSpace(ldapDn) Then
            Return New PrincipalContext(ContextType.Domain, domain)
        Else
            Return New PrincipalContext(ContextType.Domain, domain, ldapDn)
        End If
    Catch ex As PrincipalOperationException
        Return Nothing
    End Try
End Function

答案 1 :(得分:0)

您可以在PrincipalContext构造函数中指定用户名和密码以连接到商店。这是MSDN documentation链接。

答案 2 :(得分:-1)

处理此问题的最简单方法是设置WCF服务以处理与Active Directory的交互,并让您的Web应用程序查询在特权帐户下运行的服务。这样只需要提升服务,客户端就需要能够到达服务。