2

How can I get the distinguished name from Active Directory of the currently logged in user in C#?

WSBT
  • 33,033
  • 18
  • 128
  • 133
Tunc Jamgocyan
  • 321
  • 2
  • 7
  • 18

2 Answers2

10

Check following snippet. You have pass to Identity.Name from IPrincipal. I assume that the user is already authenticated in Active Directory (ie. using standard IIS authorization methods).

private string GetUserName(string identity)
{
    if (identity.Contains("\\"))
    {
        string[] identityList = identity.Split('\\');
        return identityList[1];
    }
    else
    {
        return identity;
    }
}

public string GetUserDn(string identity)
{            
    var userName = GetUserName(identity);   
    using (var rootEntry = new DirectoryEntry("LDAP://" + adConfiguration.ServerAddress, null, null, AuthenticationTypes.Secure))
    {       
        using (var directorySearcher = new DirectorySearcher(rootEntry, String.Format("(sAMAccountName={0})", userName)))
        {
            var searchResult = directorySearcher.FindOne();                    
            if (searchResult != null)
            {
                using (var userEntry = searchResult.GetDirectoryEntry())
                {
                    return (string)userEntry.Properties["distinguishedName"].Value;                 
                }
            }
        }                
    }   
    return null;
}        
empi
  • 15,755
  • 8
  • 62
  • 78
  • I am struggling with DirectoryEntry, I cannot use using System.DirectoryServices.DirectoryEntry as it does not exist. Any hints on this issue how I can import it? – Tunc Jamgocyan May 03 '12 at 09:54
  • It's in System.DirectoryServices – empi May 03 '12 at 09:56
  • Well, that's the problem. I have no entry for it, see: http://i.imgur.com/WrLFK.png – Tunc Jamgocyan May 03 '12 at 10:02
  • 2
    You have to add reference in your project to System.DirectoryServices - right click on project and choose Add reference. – empi May 03 '12 at 10:06
  • Ahh, that was it. Thank you. :) I am a Java programmer and I have never used C# for anything. That's why I am asking stupid questions. – Tunc Jamgocyan May 03 '12 at 10:08
  • Hm, I am getting at this line an error. using (var directorySearcher = new DirectorySearcher(rootEntry, "(sAMAccountName={0})", userName)) the third parameter has to be a string array. How can I modify this line? – Tunc Jamgocyan May 03 '12 at 10:15
  • Sorry, updated the code. I'm copying it from other solution and I have to omit some classes. For example we are using dedicated class for building filters and it handles LDAP special characters since using String.Format is not always safe. – empi May 03 '12 at 10:22
  • empi, thank you so much for your help. Would this line be correct? using (var rootEntry = new DirectoryEntry("LDAP://162.0.0.1:389", null, null, AuthenticationTypes.Secure)) – Tunc Jamgocyan May 03 '12 at 10:29
  • Port number is not necessary, just the ip. – empi May 03 '12 at 10:30
  • Well, I am struggling with the next problem. In this line var searchResult = directorySearcher.FindOne(); I get a notification from Visual Studio: COMException was unhandled... Any Idea, empi? :/ – Tunc Jamgocyan May 03 '12 at 11:10
  • How do you authenticate users? What kind of app is it (console / web)? As you can see there are 2 nulls provided to DirectoryEntry constructor that mean that authorization to AD should be based on current user context. If current thread doesn't run in the context of authenticated user then you should provide valid username and password (ie. admin credentials). If you get more exceptions post full stacktrace. – empi May 03 '12 at 11:17
  • It is a console application. Ok, I will give a try and answer if I could succeed! – Tunc Jamgocyan May 03 '12 at 11:26
  • If it is a console app then provide username and password in the constructor - http://msdn.microsoft.com/en-us/library/wh2h7eed.aspx – empi May 03 '12 at 11:29
  • One more thing - you get exception on FindOne because until then no connection with AD is established (it's only initialization code). – empi May 03 '12 at 11:31
  • To provide the username and password of the current user in the constructor would be a problem, wouldn't be? I can get the windows login name but it would not be possible to get the password of the currently logged user... My aim is that I run an exe-File who's distinguished name of the current logged in user is seen. That's why I need it (globally). – Tunc Jamgocyan May 03 '12 at 11:38
  • You don't provide current user password but some admin password to ad. Is user running the app authenticated to ad? Could you post full stacktrace of exception that you get? – empi May 03 '12 at 11:42
  • COMException: Server is not operational – Tunc Jamgocyan May 03 '12 at 11:54
  • Try with different AuthenticationTypes and just for test sake try providing username and password that you're sure is able to login to AD. – empi May 03 '12 at 11:56
  • Did you remove port number from server address? You may also try Ldp.exe for testing connection to ad outside your code: http://technet.microsoft.com/en-us/library/cc772839(v=ws.10).aspx - it's sometimes helpful. – empi May 03 '12 at 12:03
  • Dear empi, I am so sorry - it was my fault. I have used the wrong IP... Not it works like a dream. Thank you so much for your help and effort!! – Tunc Jamgocyan May 04 '12 at 06:21
  • @TuncJamgocyan could you post how your DirectoryEntry constructor looks like now? Of course change the ip and other data, but I'm interested if you're passing nulls for username and password or did you have to provide them? – empi May 04 '12 at 08:23
3

Why wouldn't you just use: System.DirectoryServices.AccountManagement.UserPrincipal.Current.DistinguishedName

John Ruiz
  • 2,371
  • 3
  • 20
  • 29