.net C中的Ldap连接#

时间:2012-10-18 07:33:55

标签: c# email ldap

我有一个可以发送电子邮件的应用程序。现在要求我使用ldap来验证用户电子邮件。我对这个概念很陌生。我收到了ldap服务器链接。不知道如何继续这样做。任何文章或点击都会有很大帮助。

以下是我正在尝试的代码

public static UserDetail GetUserDetails(string EmailId, string domainName)
{
    UserDetail userDetail = new UserDetail();

    try
    {
        string filter = string.Format("(&(ObjectClass={0})(sAMAccountName={1}))", "person", EmailId);
        string[] properties = new string[] { "fullname" };

        DirectoryEntry adRoot = new DirectoryEntry("LDAP://" + domainName, null, null, AuthenticationTypes.Secure);
        DirectorySearcher searcher = new DirectorySearcher(adRoot);
        searcher.SearchScope = SearchScope.Subtree;
        searcher.ReferralChasing = ReferralChasingOption.All;
        searcher.PropertiesToLoad.AddRange(properties);
        searcher.Filter = filter;
        SearchResult result = searcher.FindOne();

        DirectoryEntry directoryEntry = result.GetDirectoryEntry();
        string displayName = directoryEntry.Properties["displayName"[0].ToStrin();
        string firstName = directoryEntry.Properties["givenName"][0].ToString();
        string lastName = directoryEntry.Properties["sn"][0].ToString();
        string emailId = directoryEntry.Properties["mail"][0].ToString();

        userDetail.EmailId = emailId;
    }
    catch (Exception)
    {

    }
    return userDetail;
}

我想点击搜索按钮来实现它。如何调用方法并传递变量。

3 个答案:

答案 0 :(得分:3)

如果您使用的是.NET 3.5或更高版本,则可以使用PrincipalSearcher和“按示例查询”主体进行搜索:

// create your domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// define a "query-by-example" principal - here, we search for a UserPrincipal 
// and with the e-mail of "bruce@example.com"
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.EmailAddress = "bruce@example.com";

// create your principal searcher passing in the QBE principal    
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);

// try to find that user
UserPrincipal found = srch.FindOne() as UserPrincipal;

if(found != null)
{
    // do whatever here - "found" is the user that matched the e-mail given
}
else
{
    // there wasn't any user with that e-mail address in your AD
}

如果您还没有 - 绝对阅读MSDN文章Managing Directory Security Principals in the .NET Framework 3.5,该文章很好地展示了如何充分利用System.DirectoryServices.AccountManagement中的新功能。或者查看MSDN documentation on the System.DirectoryServices.AccountManagement命名空间。

当然,根据您的需要,您可能希望在您创建的“按示例查询”用户主体上指定其他属性:

  • DisplayName(通常:名字+空格+姓氏)
  • SAM Account Name - 您的Windows / AD帐户名称
  • User Principal Name - 您的“username@yourcompany.com”样式名称

您可以在UserPrincipal上指定任何属性,并将其用作PrincipalSearcher的“按示例查询”。

答案 1 :(得分:1)

如果输入了emailAddress(类型字符串),则此代码将在LDAP目录中搜索具有匹配电子邮件地址的用户,并返回有关该用户的一些信息:

string fullName = string.Empty;
            string givenName = string.Empty;
            string distinguishedName = string.Empty;
            string sAMAccountName = string.Empty;
            using (var context = new PrincipalContext(ContextType.Domain, "DOMAIN"))
            {
                using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
                {
                    foreach (Principal result in searcher.FindAll())
                    {
                        var de = result.GetUnderlyingObject() as DirectoryEntry;

                        if (de.Properties["cn"].Value.ToString().Contains(" "))
                        {

                            //var userEntry = new DirectoryUser(de.Properties["sAMAccountName"].Value.ToString());
                            var currentUserEmail = de.Properties["mail"].Value.ToString().ToLower();
                            if (currentUserEmail == emailAddress)
                            {

                                if (de.Properties["cn"].Value != null)
                                    fullName = de.Properties["cn"].Value.ToString();
                                if (de.Properties["givenName"].Value != null)
                                   givenName = de.Properties["givenName"].Value.ToString();
                                if (de.Properties["distinguishedName"].Value != null)
                                    distinguishedName =de.Properties["distinguishedName"].Value.ToString();
                                if (de.Properties["sAMAccountName"].Value != null)
                                    sAMAccountName = de.Properties["sAMAccountName"].Value.ToString();


                            }
                        }
                    }
                }
            }

需要参考:

System.DirectoryServices;
System.DirectoryServices.AccountManagement;

我想提一个警告,目录查找例程可能会很慢。如果您的域中有100,000个用户,则此过程将需要一段时间才能运行。我倾向于做的是,定期将目录搜索的输出转储到数据库表,并对该表执行任何查找。数据库转储的频率当然取决于您的业务逻辑。有时我只是在执行新转储之前截断表格,而在其他情况下,我会转移到一个“转储”状态。表格,只适用于delta'更新活动的directoy记录表。

答案 2 :(得分:0)

  • 如果可能,使用SSL连接到目录服务器。使用StartTLS扩展操作也可以促进与安全连接的非安全连接。
  • 将SEARCH请求发送到服务器,该服务器包含客户端希望从中开始搜索的基本DN,搜索范围(基本,一级或子树),使用LDAP信息的过滤器客户端知道会将搜索结果缩小到所需的用户,以及属性1.1
  • 服务器将使用SEARCH响应进行响应,该响应包含与搜索请求参数匹配的条目数以及匹配的每个条目的可分辨名称。
  • 通过安全连接将BIND请求传输到目录服务器。 BIND请求包含专有名称和专有名称的凭据
  • 目录服务器将验证凭据并返回带有整数结果代码的BIND响应,指示凭据是否与存储在服务器数据库中的凭据相匹配

另见