【问题标题】:How to get a user's e-mail address from Active Directory?如何从 Active Directory 中获取用户的电子邮件地址?
【发布时间】:2009-04-24 11:53:23
【问题描述】:

我试图在 AD 中获取用户的电子邮件地址,但没有成功。

String account = userAccount.Replace(@"Domain\", "");
DirectoryEntry entry = new DirectoryEntry();

try {
    DirectorySearcher search = new DirectorySearcher(entry);

    search.PropertiesToLoad.Add("mail");  // e-mail addressead

    SearchResult result = search.FindOne();
    if (result != null) {
        return result.Properties["mail"][0].ToString();
    } else {
        return "Unknown User";
    }
} catch (Exception ex) {
    return ex.Message;
}

任何人都可以看到问题或指出正确的方向吗?

【问题讨论】:

    标签: c# active-directory


    【解决方案1】:

    免责声明:此代码不会搜索single exact match,因此对于domain\j_doe,如果还存在类似名称的帐户,它可能会返回domain\j_doe_from_external_department 的电子邮件地址。如果不希望出现这种行为,请使用samAccountName 过滤器而不是下面使用的anr 过滤器,或者另外过滤results

    我已成功使用此代码(其中“帐户”是不带域(域\帐户)的用户登录名:

    // get a DirectorySearcher object
    DirectorySearcher search = new DirectorySearcher(entry);
    
    // specify the search filter
    search.Filter = "(&(objectClass=user)(anr=" + account + "))";
    
    // specify which property values to return in the search
    search.PropertiesToLoad.Add("givenName");   // first name
    search.PropertiesToLoad.Add("sn");          // last name
    search.PropertiesToLoad.Add("mail");        // smtp mail address
    
    // perform the search
    SearchResult result = search.FindOne();
    

    【讨论】:

    • 是的,对我也有用。是的也需要调用语法... Response.Write(result.Properties["givenName"][0].ToString()); Response.Write("
      "); Response.Write(result.Properties["sn"][0].ToString()); Response.Write("
      "); Response.Write(result.Properties["mail"][0].ToString()); Response.Write("
      "); Response.Write(FindName("gruberj"));
    • 我不得不使用 (&(objectCategory=person)(objectClass=user)(anr=" + account + "))"; 因为第一个结果是我刚刚使用 objectClass=user 的计算机
    • 把这个在我们的域上工作的要点放在一起:gist.github.com/roufamatic/8442829
    • anr 在上面的查询中是“模糊名称解析”,因此进行模糊匹配。如果您想要完全匹配,请在上面的代码中使用 sAMAccountName 而不是 anr
    • 您可能还需要这个:AD manageengine.com/products/ad-manager/help/csv-import-management/…中与用户关联的所有属性列表
    【解决方案2】:

    你们太辛苦了:

    // Look up the current user's email address
    string eMail =  UserPrincipal.Current.EmailAddress;
    

    【讨论】:

    • UserPrincipal 是什么? 命名空间和程序集 ?
    • 很好,需要引用 System.DirectoryServices.AccountManagement 并且不需要像当前那样登录。
    • 你的帖子比原来的答案晚了 8 年 - 但嘿,我现在正在看 - 所以我将在 7 上取 1 行 ...
    • OP 没有询问是否要查找当前用户的电子邮件 - 即使他们这样做了,也假定该应用正在使用域身份验证。
    【解决方案3】:

    您可以尝试下面的 GetUserEmail 方法。如果您想在 MVC 中查找登录用户的电子邮件地址,请使用 User.Identity.Name

    调用 GetUserEmail() 函数
    using System.DirectoryServices;
    using System.Linq;
    
    public string GetUserEmail(string UserId)
        {
    
            var searcher = new DirectorySearcher("LDAP://" + UserId.Split('\\').First().ToLower())
            {
                Filter = "(&(ObjectClass=person)(sAMAccountName=" + UserId.Split('\\').Last().ToLower() + "))"
            };
    
            var result = searcher.FindOne();
            if (result == null)
                return string.Empty;
    
            return result.Properties["mail"][0].ToString();
    
        }
    
    GetUserEmail(User.Identity.Name) //Get Logged in user email address
    

    【讨论】:

      【解决方案4】:

      您忘记了过滤器。

      在调用 FindOne 之前尝试添加:

      search.Filter = String.Format("(sAMAccountName={0})", account);
      

      【讨论】:

      • 值在放入过滤器字符串之前必须进行转义(tools.ietf.org/html/rfc4515#section-3ff.)
      • 我认为有更好的方法。您可以将搜索范围设置为SearchScope.Base,在这种情况下,搜索可能检索到的唯一对象您提供的根对象。我很确定那时不需要显式过滤。
      【解决方案5】:

      这个呢

      public string GetEmailFromSamAccountName(string samAccountName, string domain="YOURCOMPANY")
      {
         using (var principalContext = new PrincipalContext(ContextType.Domain, domain))
         {
            var userPrincipal = UserPrincipal.FindByIdentity(principalContext, samAccountName);
            return userPrincipal.EmailAddress;
         }
      }
      

      【讨论】:

        【解决方案6】:

        另外,您从哪里提取用户名(存储、用户输入、当前身份)?用户名可以轻松更改(重命名) - 另一方面,SID/Windows 登录身份不会改变 - 因此,如果可能和/或需要设计,最好通过 SID 而不是 samaccountname 进行过滤/搜索。 ..

        【讨论】:

          【解决方案7】:

          您需要为 System.DirectoryServices.AccountManagement 添加引用,并在您的 using 语句中包含相同的引用。现在,您将可以访问下面列出的当前用户登录详细信息,包括电子邮件地址。

          string loginname = Environment.UserName;
          string firstname = UserPrincipal.Current.GivenName;
          string lastname = UserPrincipal.Current.Surname;
          string name = UserPrincipal.Current.Name;
          string eMail = UserPrincipal.Current.EmailAddress;
          

          【讨论】:

          • 我认为他们不是在询问当前用户 - 他们想查找特定用户 -
          【解决方案8】:

          更新:弗雷德里克成功了....

          雅各布是对的。您需要过滤您的搜索。如果需要,您也可以在那里执行各种ands 和ors,但我认为sAMAccountName 就足够了。您可能想要启动 ADSI 工具(我认为它在资源工具包中),它可以让您像注册表一样使用 AD。非常适合查看属性。然后找到一个用户,找出你想要的道具(在这种情况下是邮件)以及它的 primary key 是什么 - sAMAccountName 是一个很好的,但你可能还想过滤节点类型。

          我在 Mac 上,因此无法为您检查,但 AD 中的每个节点都有一个类型,您可以将其添加到您的过滤器中。我认为它看起来像这样:

          ((sAMAccountName=bob) & (type=User))
          

          再次检查一下 - 我知道它不是 type=user,而是类似的东西。

          【讨论】:

            猜你喜欢
            • 2013-04-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多