开发者

Correct method to search for AD user by email address from .NET

开发者 https://www.devze.com 2022-12-24 18:35 出处:网络
I\'m having some issues with code that is intended to find a user in Active Directory by searching on their email address. I have tried 2 methods but I\'m sometimes finding that the FindOne() method w

I'm having some issues with code that is intended to find a user in Active Directory by searching on their email address. I have tried 2 methods but I'm sometimes finding that the FindOne() method will not return any results on some occasions. If I look up the user in the GAL in Outlook I see the SMTP email address listed.

My end goal is to confirm that the user exists in AD. I only have the email address as search criteria, so no way to use first or last name.

Method 1: Using mail property:

DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(mail=" + email + ")";
search.PropertiesToLoad.Add("mail");
SearchResult result = search.FindOne();

Method 2: proxyAddresses property:

DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(proxyAddresses=SM开发者_开发问答TP:" + email + ")"; // I've also tried with =smtp:
search.PropertiesToLoad.Add("mail");
SearchResult result = search.FindOne();

I've tried changing the case of the email address input but it still does not return a result. Is there a problem here with case sensitivity? If so, what is the best way to resolve it?


If you are using Exchange Server, proxyAddresses is the most reliable means of getting their email address. The primary smtp address is indicated by all caps "SMTP:" and additional email addresses will be prefixed with lowercase "smtp:". The attribute "mail" does not necessarily have to be the primary SMTP address, though usually it is.

Here is a variation of some code I used:

    public static SearchResult FindAccountByEmail(string email)
    {
        string filter = string.Format("(proxyaddresses=SMTP:{0})", email);

        using (DirectoryEntry gc = new DirectoryEntry("GC:"))
        {
            foreach (DirectoryEntry z in gc.Children)
            {
                using (DirectoryEntry root = z)
                {
                    using (DirectorySearcher searcher = new DirectorySearcher(root, filter, new string[] { "proxyAddresses", "objectGuid", "displayName", "distinguishedName" }))
                    {
                        searcher.ReferralChasing = ReferralChasingOption.All;
                        SearchResult result = searcher.FindOne();

                        return result;
                    }
                }
                break;
            }
        }

        return null;
    }

    static void Main(string[] args)
    {
        SearchResult result = FindAccountByEmail("someone@somewhere.com");

        string distinguishedName = result.Properties["distinguishedName"][0] as string;
        string name = result.Properties["displayName"] != null
                        ? result.Properties["displayName"][0] as string
                        : string.Empty;
        Guid adGuid = new Guid((byte[]) (result.Properties["objectGUID"][0]));

        string emailAddress;
        var emailAddresses = (from string z in result.Properties["proxyAddresses"]
                              where z.StartsWith("SMTP")
                              select z);
        emailAddress = emailAddresses.Count() > 0 ? emailAddresses.First().Remove(0, 5) : string.Empty;


        Console.WriteLine(string.Format("{1}{0}\t{2}{0}\t{3}{0}\t{4}",
                      Environment.NewLine,
                      name,
                      distinguishedName,
                      adGuid,
                      emailAddress));
    }


I've found that using SysInternals ADExplorer is great for testing out/debugging Active Directory queries. As you can build the queries and run them against Active Directory you can see the results as well as easily view objects and see all their properties...


I've never had any issues with case sensitivity searching for users' email addresses - what happens if you search for the address, exactly as it appears in ADSIEDIT? Does it find the address when it is cased correctly?

BTW, I've always used the "mail" property, as it returns the user's single default outgoing email address, even if there are multiple addresses attached to the account. The "proxyAddresses" property is actually a multi-value property, and you're just searching for the value that starts with "smtp:" (it's lowercase in the property). However, a user could have multiple SMTP addresses on their AD account (we do), so between the two, the "mail" property may be what you're looking for.


var ds = new DirectorySearcher(new DirectoryEntry(strLDAPDomain));
ds.Filter = "(&(|(objectClass=User)(objectCategory=Person))(anr=" + user.userId + "))";// "(Name=*" + search + "*)";
                    
ds.PropertiesToLoad.Add("mail");

var results = ds.FindOne();
if (results.Properties["mail"].Count > 0)
{
    objUserInfo.UserEmail = results.Properties["mail"][0].ToString();
}
else
{
    objUserInfo.UserEmail = user.useridID + "@gmail.com";
}
0

精彩评论

暂无评论...
验证码 换一张
取 消