Active Directory

Discussion in 'ASP .Net Security' started by Bob Mixon, Jan 13, 2007.

  1. Bob Mixon

    Bob Mixon Guest

    Greetings All,

    Being a little less familiar with accessing AD, can someone tell me the best
    way to obtain an AD user record (profile). Ultimately I would like to simply
    obtain the manager that has been assigned to a specific user.

    Thank you in advance for the help!

    Bob Mixon [SPS MVP]
    http://www.ShareSquared.com
    http://www.ShareSquared.com/blogs/BobMixo
     
    Bob Mixon, Jan 13, 2007
    #1
    1. Advertising

  2. >Being a little less familiar with accessing AD, can someone tell me the best
    >way to obtain an AD user record (profile). Ultimately I would like to simply
    >obtain the manager that has been assigned to a specific user.


    You will need to bind to the user's AD object - this requires that you
    understand what LDAP path names are,and how to construct those.

    Something like: LDAP://yourserver01.domain.com/cn=Bob
    Mixon,OU=IT,OU=Headquarters,dc=domain,dc=com

    In order to be able to bind to an AD object, you'll need to add a
    reference to the "System.DirectoryServices" assembly to your project,
    and add a "using System.DirectoryServices" line into your code.

    From there, you bind to the user by constructing a DirectoryEntry
    object instance:

    string ldapPath = "LDAP://yourserver01.domain.com/cn=Bob
    Mixon,OU=IT,OU=Headquarters,dc=domain,dc=com";

    DirectoryEntry deUser = new DirectoryEntry(ldapPath);

    Once you have a "deUser" object, you can query for any valid LDAP
    property, e.g. things like "givenName" (first name), "sn" (surname =
    last name), "mail" (e-mail address) and so forth.

    string firstName = deUser.Properties["givenName"].Value;

    and so forth.

    For more info, I'd suggest

    * the MSDN portal for System.DirectoryServices
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sds/sds/portal.asp

    * Joe Kaplan and Ryan Dunn's outstanding book on S.DS programming (the
    "bible" for any S.DS programmer, really)

    The .NET Developer's Guide to Directory Services Programming
    http://www.amazon.com/Developers-Di..._bbs_sr_1/104-3503577-8887962?ie=UTF8&s=books

    * my C# ADSI object browser called "BeaverTail" (free and with source
    code):
    http://adsi.mvps.org/adsi/CSharp/beavertail.html

    Cheers!
    Marc
     
    Marc Scheuner, Jan 13, 2007
    #2
    1. Advertising

  3. Bob Mixon

    Bob Mixon Guest

    Hi Marc,

    I really appreciate your response. I have done quite a bit of reading and
    am still struggling with getting this to work. I am a seasoned developer,
    just not with using Directory Services and LDAP.

    Here is what I have. I have a Windows 2003 Server VM that I use for SharePoint
    development efforts. In this type of "sandbox" environment, it is very common
    to have everything installed on the single server. This VM is an AD DC,
    running SQL Server 2005 and MOSS. I understand this won't be the same in
    a "real" production environment. The server is named "w2k3" and the domain
    is simply "moss".

    I am first trying to simply see if an LDAP entry exist. The entry "LDAP://DC=moss"
    returns a valid DirectoryService object instance. And so does "LDAP://DC=moss/CN=Users".
    However, the entry "LDAP://DC=moss/CN=Bob Mixon" and "LDAP://DC=moss,CN=Bob
    Mixon" both fail. The account "Bob Mixon" is valid in AD; i.e. user id bob.mixon,
    name "Bob Mixon".

    Ultimately all I want to do is locate a user account then retrieve that users
    manager information. This can't be that difficult.

    Thank you for your time! :)

    Bob Mixon [Microsoft SharePoint MVP]
    http://www.ShareSquared.com
    http://www.ShareSquared.com/blogs/BobMixon

    >> Being a little less familiar with accessing AD, can someone tell me
    >> the best way to obtain an AD user record (profile). Ultimately I
    >> would like to simply obtain the manager that has been assigned to a
    >> specific user.
    >>

    > You will need to bind to the user's AD object - this requires that you
    > understand what LDAP path names are,and how to construct those.
    >
    > Something like: LDAP://yourserver01.domain.com/cn=Bob
    > Mixon,OU=IT,OU=Headquarters,dc=domain,dc=com
    >
    > In order to be able to bind to an AD object, you'll need to add a
    > reference to the "System.DirectoryServices" assembly to your project,
    > and add a "using System.DirectoryServices" line into your code.
    >
    > From there, you bind to the user by constructing a DirectoryEntry
    > object instance:
    >
    > string ldapPath = "LDAP://yourserver01.domain.com/cn=Bob
    > Mixon,OU=IT,OU=Headquarters,dc=domain,dc=com";
    >
    > DirectoryEntry deUser = new DirectoryEntry(ldapPath);
    >
    > Once you have a "deUser" object, you can query for any valid LDAP
    > property, e.g. things like "givenName" (first name), "sn" (surname =
    > last name), "mail" (e-mail address) and so forth.
    >
    > string firstName = deUser.Properties["givenName"].Value;
    >
    > and so forth.
    >
    > For more info, I'd suggest
    >
    > * the MSDN portal for System.DirectoryServices
    > http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sds/s
    > ds/portal.asp
    > * Joe Kaplan and Ryan Dunn's outstanding book on S.DS programming (the
    > "bible" for any S.DS programmer, really)
    >
    > The .NET Developer's Guide to Directory Services Programming
    >
    > http://www.amazon.com/Developers-Directory-Programming-Microsoft-Devel
    > opment/dp/0321350170/sr=8-1/qid=1168695760/ref=pd_bbs_sr_1/104-3503577
    > -8887962?ie=UTF8&s=books
    >
    > * my C# ADSI object browser called "BeaverTail" (free and with source
    > code):
    > http://adsi.mvps.org/adsi/CSharp/beavertail.html
    > Cheers!
    > Marc
     
    Bob Mixon, Jan 14, 2007
    #3
  4. Bob Mixon

    Joe Kaplan Guest

    Hi Bob,

    There is no way those paths you have are going to be working correctly.
    LDAP distinguished names (DN) are similar to file system paths in that they
    suggest the directory hierarchy, but with three key differences:
    - They are listed in opposite order (most specific first instead of last
    like a file system path)
    - Each component in the hierarchy has a two part name called a relative
    distinguished name (RDN) that is made up of the naming attribute and value.
    For example, CN=someuser could be an RDN where CN is the naming attribute
    and someuser is the value of CN for that object. AD uses just three naming
    attributes: CN, OU and DC, although LDAP in general can be much more varied.
    - The top level object in the hierarchy (called the naming context name or
    domain root in some cases) may consist of more than one RDN component. For
    example, you might have the NC name as DC=domain,DC=com.

    As such, a typical DN for a user might be
    CN=someuser,CN=Users,DC=domain,DC=com. Here, CN=someuser points to the user
    object, CN=Users points to the default container in AD where users are
    stored and DC=domain,DC=com points to the domain root.

    Now, with an ADsPath (which is used by ADSI and System.DirectoryServices),
    the path is a combo of the provider, the server (which can be optional) and
    the object name. It goes like:

    <provider>://<server>/<object>

    In LDAP, the provider is always "LDAP" (upper case is important) unless you
    are talking to the global catalog, in which it is GC. The server name is
    optional and can be the DNS name of the DC, the DNS name of the domain, the
    NetBIOS name of the domain or the IP address of the DC. I generally
    recommend using either the DNS name of the domain or nothing (called
    "serverless binding" in ADSI terms). However, when you use nothing, ADSI
    uses the current security context of the thread to figure out what domain to
    contact and this can get complex in web apps, so you can get unexpected
    failures this way. Adding the domain name is safe. The object name is the
    distinguished name of the object. As such, a valid ADsPath for the DN of
    the example object above might be:

    LDAP://domain.com/CN=someuser,CN=Users,DC=domain,DC=com

    or

    LDAP://mydc.domain.com/CN=someuser,CN=Users,DC=domain,DC=com

    or

    LDAP://CN=someuser,CN=Users,DC=domain,DC=com

    Remember that with S.DS, the constructor doesn't actually bind the object
    (it is late binding), so you'll generally get an object back when you use
    the constructor. It will just fail later when you attempt to use it. This
    is a little different than ADSI in VB or VBScript.

    My recommendation would be to pick up Marc's browser that he wrote (good
    sample code inside) or just get LDP.exe which comes with ADAM or the Windows
    adminpack. I like it especially, as it is sort of the "query analyzer" for
    LDAP. It kind of forces you to know what you are doing, but it also shows
    you exactly what is going and and can really help you prototype your
    queries.

    My book (that Marc aluded to) has a bunch of other helpful stuff. You may
    run into issues related to security context when you move this into
    production and have everything on different boxes. It is very much like
    getting SSPI auth to work with a remote SQL server. You need to understand
    security context and delegation quite well, especially if you are using
    impersonation and want to connect to AD as the authenticated user instead of
    the app pool process identity.

    LDAP can be an annoying struggle for those seeing it for the first time,
    even for experienced devs like you, but it all comes together once you get a
    few things down.

    Joe K.

    --
    Joe Kaplan-MS MVP Directory Services Programming
    Co-author of "The .NET Developer's Guide to Directory Services Programming"
    http://www.directoryprogramming.net
    --
    "Bob Mixon" <> wrote in message
    news:...
    > Hi Marc,
    >
    > I really appreciate your response. I have done quite a bit of reading and
    > am still struggling with getting this to work. I am a seasoned developer,
    > just not with using Directory Services and LDAP.
    >
    > Here is what I have. I have a Windows 2003 Server VM that I use for
    > SharePoint development efforts. In this type of "sandbox" environment, it
    > is very common to have everything installed on the single server. This VM
    > is an AD DC, running SQL Server 2005 and MOSS. I understand this won't be
    > the same in a "real" production environment. The server is named "w2k3"
    > and the domain is simply "moss".
    >
    > I am first trying to simply see if an LDAP entry exist. The entry
    > "LDAP://DC=moss" returns a valid DirectoryService object instance. And so
    > does "LDAP://DC=moss/CN=Users". However, the entry "LDAP://DC=moss/CN=Bob
    > Mixon" and "LDAP://DC=moss,CN=Bob Mixon" both fail. The account "Bob
    > Mixon" is valid in AD; i.e. user id bob.mixon, name "Bob Mixon".
    >
    > Ultimately all I want to do is locate a user account then retrieve that
    > users manager information. This can't be that difficult.
    >
    > Thank you for your time! :)
    >
    > Bob Mixon [Microsoft SharePoint MVP]
    > http://www.ShareSquared.com
    > http://www.ShareSquared.com/blogs/BobMixon
    >
     
    Joe Kaplan, Jan 14, 2007
    #4
  5. Bob Mixon

    Bob Mixon Guest

    Greetings Joe,

    I really appreciate all of the information. I am going to go ahead and purchase
    your book. I didn't really want to have to go through all of this but I
    don't see any way around it. :)

    In the meantime I have a couple of additional questions. When I am specifying
    the user name (CN), is it the user name or account name?

    Thank you again and I will keep you posted on my progress!

    Bob Mixon [Microsoft SharePoint MVP]
    http://www.ShareSquared.com
    http://www.ShareSquared.com/blogs/BobMixon

    > Hi Bob,
    >
    > There is no way those paths you have are going to be working
    > correctly.
    > LDAP distinguished names (DN) are similar to file system paths in that
    > they
    > suggest the directory hierarchy, but with three key differences:
    > - They are listed in opposite order (most specific first instead of
    > last
    > like a file system path)
    > - Each component in the hierarchy has a two part name called a
    > relative
    > distinguished name (RDN) that is made up of the naming attribute and
    > value.
    > For example, CN=someuser could be an RDN where CN is the naming
    > attribute
    > and someuser is the value of CN for that object. AD uses just three
    > naming
    > attributes: CN, OU and DC, although LDAP in general can be much more
    > varied.
    > - The top level object in the hierarchy (called the naming context
    > name or
    > domain root in some cases) may consist of more than one RDN component.
    > For
    > example, you might have the NC name as DC=domain,DC=com.
    >
    > As such, a typical DN for a user might be
    > CN=someuser,CN=Users,DC=domain,DC=com. Here, CN=someuser points to
    > the user object, CN=Users points to the default container in AD where
    > users are stored and DC=domain,DC=com points to the domain root.
    >
    > Now, with an ADsPath (which is used by ADSI and
    > System.DirectoryServices), the path is a combo of the provider, the
    > server (which can be optional) and the object name. It goes like:
    >
    > <provider>://<server>/<object>
    >
    > In LDAP, the provider is always "LDAP" (upper case is important)
    > unless you are talking to the global catalog, in which it is GC. The
    > server name is optional and can be the DNS name of the DC, the DNS
    > name of the domain, the NetBIOS name of the domain or the IP address
    > of the DC. I generally recommend using either the DNS name of the
    > domain or nothing (called "serverless binding" in ADSI terms).
    > However, when you use nothing, ADSI uses the current security context
    > of the thread to figure out what domain to contact and this can get
    > complex in web apps, so you can get unexpected failures this way.
    > Adding the domain name is safe. The object name is the distinguished
    > name of the object. As such, a valid ADsPath for the DN of the
    > example object above might be:
    >
    > LDAP://domain.com/CN=someuser,CN=Users,DC=domain,DC=com
    >
    > or
    >
    > LDAP://mydc.domain.com/CN=someuser,CN=Users,DC=domain,DC=com
    >
    > or
    >
    > LDAP://CN=someuser,CN=Users,DC=domain,DC=com
    >
    > Remember that with S.DS, the constructor doesn't actually bind the
    > object (it is late binding), so you'll generally get an object back
    > when you use the constructor. It will just fail later when you
    > attempt to use it. This is a little different than ADSI in VB or
    > VBScript.
    >
    > My recommendation would be to pick up Marc's browser that he wrote
    > (good sample code inside) or just get LDP.exe which comes with ADAM or
    > the Windows adminpack. I like it especially, as it is sort of the
    > "query analyzer" for LDAP. It kind of forces you to know what you are
    > doing, but it also shows you exactly what is going and and can really
    > help you prototype your queries.
    >
    > My book (that Marc aluded to) has a bunch of other helpful stuff. You
    > may run into issues related to security context when you move this
    > into production and have everything on different boxes. It is very
    > much like getting SSPI auth to work with a remote SQL server. You
    > need to understand security context and delegation quite well,
    > especially if you are using impersonation and want to connect to AD as
    > the authenticated user instead of the app pool process identity.
    >
    > LDAP can be an annoying struggle for those seeing it for the first
    > time, even for experienced devs like you, but it all comes together
    > once you get a few things down.
    >
    > Joe K.
    >
     
    Bob Mixon, Jan 16, 2007
    #5
  6. Bob Mixon

    Joe Kaplan Guest

    The CN is the CN. :) It is not the account name, as that is stored in the
    sAMAccountName attribute (the username in "domain\username"). Unfortunately
    AD has a ton of naming attributes (CN, userPrincipalName, sAMAccountName,
    displayName, givenName, SN, etc.), so it can be confusing.

    It is often the case that CN will be the same as sAMAccountName, but that
    would just be by convention. The directory doesn't enforce that.

    If you have the logon name and need to find the user in the directory, you
    typically have to use the DirectorySearcher to search for them with a filter
    like:

    (sAMAccountName=username)

    I do appreciate you buying my book. Thanks. :) I'm happy to continue to
    help either way, but it may save you a bunch of trouble. I'm sure Marc will
    be happy to jump in as well if I give him half a chance. He knows this
    stuff real well too. :)

    Joe K.

    --
    Joe Kaplan-MS MVP Directory Services Programming
    Co-author of "The .NET Developer's Guide to Directory Services Programming"
    http://www.directoryprogramming.net
    --
    "Bob Mixon" <> wrote in message
    news:...
    > Greetings Joe,
    >
    > I really appreciate all of the information. I am going to go ahead and
    > purchase your book. I didn't really want to have to go through all of
    > this but I don't see any way around it. :)
    >
    > In the meantime I have a couple of additional questions. When I am
    > specifying the user name (CN), is it the user name or account name?
    >
    > Thank you again and I will keep you posted on my progress!
    >
    > Bob Mixon [Microsoft SharePoint MVP]
    > http://www.ShareSquared.com
    > http://www.ShareSquared.com/blogs/BobMixon
    >
    >> Hi Bob,
    >>
    >> There is no way those paths you have are going to be working
    >> correctly.
    >> LDAP distinguished names (DN) are similar to file system paths in that
    >> they
    >> suggest the directory hierarchy, but with three key differences:
    >> - They are listed in opposite order (most specific first instead of
    >> last
    >> like a file system path)
    >> - Each component in the hierarchy has a two part name called a
    >> relative
    >> distinguished name (RDN) that is made up of the naming attribute and
    >> value.
    >> For example, CN=someuser could be an RDN where CN is the naming
    >> attribute
    >> and someuser is the value of CN for that object. AD uses just three
    >> naming
    >> attributes: CN, OU and DC, although LDAP in general can be much more
    >> varied.
    >> - The top level object in the hierarchy (called the naming context
    >> name or
    >> domain root in some cases) may consist of more than one RDN component.
    >> For
    >> example, you might have the NC name as DC=domain,DC=com.
    >>
    >> As such, a typical DN for a user might be
    >> CN=someuser,CN=Users,DC=domain,DC=com. Here, CN=someuser points to
    >> the user object, CN=Users points to the default container in AD where
    >> users are stored and DC=domain,DC=com points to the domain root.
    >>
    >> Now, with an ADsPath (which is used by ADSI and
    >> System.DirectoryServices), the path is a combo of the provider, the
    >> server (which can be optional) and the object name. It goes like:
    >>
    >> <provider>://<server>/<object>
    >>
    >> In LDAP, the provider is always "LDAP" (upper case is important)
    >> unless you are talking to the global catalog, in which it is GC. The
    >> server name is optional and can be the DNS name of the DC, the DNS
    >> name of the domain, the NetBIOS name of the domain or the IP address
    >> of the DC. I generally recommend using either the DNS name of the
    >> domain or nothing (called "serverless binding" in ADSI terms).
    >> However, when you use nothing, ADSI uses the current security context
    >> of the thread to figure out what domain to contact and this can get
    >> complex in web apps, so you can get unexpected failures this way.
    >> Adding the domain name is safe. The object name is the distinguished
    >> name of the object. As such, a valid ADsPath for the DN of the
    >> example object above might be:
    >>
    >> LDAP://domain.com/CN=someuser,CN=Users,DC=domain,DC=com
    >>
    >> or
    >>
    >> LDAP://mydc.domain.com/CN=someuser,CN=Users,DC=domain,DC=com
    >>
    >> or
    >>
    >> LDAP://CN=someuser,CN=Users,DC=domain,DC=com
    >>
    >> Remember that with S.DS, the constructor doesn't actually bind the
    >> object (it is late binding), so you'll generally get an object back
    >> when you use the constructor. It will just fail later when you
    >> attempt to use it. This is a little different than ADSI in VB or
    >> VBScript.
    >>
    >> My recommendation would be to pick up Marc's browser that he wrote
    >> (good sample code inside) or just get LDP.exe which comes with ADAM or
    >> the Windows adminpack. I like it especially, as it is sort of the
    >> "query analyzer" for LDAP. It kind of forces you to know what you are
    >> doing, but it also shows you exactly what is going and and can really
    >> help you prototype your queries.
    >>
    >> My book (that Marc aluded to) has a bunch of other helpful stuff. You
    >> may run into issues related to security context when you move this
    >> into production and have everything on different boxes. It is very
    >> much like getting SSPI auth to work with a remote SQL server. You
    >> need to understand security context and delegation quite well,
    >> especially if you are using impersonation and want to connect to AD as
    >> the authenticated user instead of the app pool process identity.
    >>
    >> LDAP can be an annoying struggle for those seeing it for the first
    >> time, even for experienced devs like you, but it all comes together
    >> once you get a few things down.
    >>
    >> Joe K.
    >>

    >
    >
     
    Joe Kaplan, Jan 16, 2007
    #6
  7. >In the meantime I have a couple of additional questions. When I am specifying
    >the user name (CN), is it the user name or account name?


    The CN (common name) is really the *object* name of the AD object -
    which as Joe points out really doesn't necessarily have anything to do
    with your user name (first and last name), nor his (or her) account
    name (as in Win NT account, "domain\user").

    Confusing? Maybe - just think of it that way - you could leave you AD
    object alone (it's CN), while still changing first name, last name,
    account name, and a plethora of other names, too - but your OBJECT
    name is still the same.

    Marc
     
    Marc Scheuner, Jan 16, 2007
    #7
  8. Bob Mixon

    Bob Mixon Guest

    Hey Joe and Marc,

    I really approciate all of your help; I did get things working. After following
    all of your direction, I was still having a few problems and it was due to
    my using the incorrect FQDN. My domain is simply 'moss' so I had to use
    "DC=moss,DC=local"; the "DC=local" is the part I wasn't providing.

    Bob Mixon [SPS MVP]
    http://www.ShareSquared.com
    http://www.ShareSquared.com/blogs/BobMixon

    >> In the meantime I have a couple of additional questions. When I am
    >> specifying the user name (CN), is it the user name or account name?
    >>

    > The CN (common name) is really the *object* name of the AD object -
    > which as Joe points out really doesn't necessarily have anything to do
    > with your user name (first and last name), nor his (or her) account
    > name (as in Win NT account, "domain\user").
    >
    > Confusing? Maybe - just think of it that way - you could leave you AD
    > object alone (it's CN), while still changing first name, last name,
    > account name, and a plethora of other names, too - but your OBJECT
    > name is still the same.
    >
    > Marc
    >
     
    Bob Mixon, Jan 20, 2007
    #8
  9. Bob Mixon

    Joe Kaplan Guest

    Glad you got it working. Tools like ADSI Edit and ldp.exe can really help
    with these types of issues in case you end up having to walk up to an AD you
    aren't familiar with in the future. They generally know how to bootstrap
    enough of the key data (such as the name of the default naming context for
    the domain and its DNS name) to get you off the ground and allow you to
    quickly test an operation before coding it and making you wonder whether the
    problem is your actual logic or just the values you are passing in.

    Joe K.

    --
    Joe Kaplan-MS MVP Directory Services Programming
    Co-author of "The .NET Developer's Guide to Directory Services Programming"
    http://www.directoryprogramming.net
    --
    "Bob Mixon" <> wrote in message
    news:...
    > Hey Joe and Marc,
    >
    > I really approciate all of your help; I did get things working. After
    > following all of your direction, I was still having a few problems and it
    > was due to my using the incorrect FQDN. My domain is simply 'moss' so I
    > had to use "DC=moss,DC=local"; the "DC=local" is the part I wasn't
    > providing.
    >
    > Bob Mixon [SPS MVP]
    > http://www.ShareSquared.com
    > http://www.ShareSquared.com/blogs/BobMixon
    >
    >>> In the meantime I have a couple of additional questions. When I am
    >>> specifying the user name (CN), is it the user name or account name?
    >>>

    >> The CN (common name) is really the *object* name of the AD object -
    >> which as Joe points out really doesn't necessarily have anything to do
    >> with your user name (first and last name), nor his (or her) account
    >> name (as in Win NT account, "domain\user").
    >>
    >> Confusing? Maybe - just think of it that way - you could leave you AD
    >> object alone (it's CN), while still changing first name, last name,
    >> account name, and a plethora of other names, too - but your OBJECT
    >> name is still the same.
    >>
    >> Marc
    >>

    >
    >
     
    Joe Kaplan, Jan 21, 2007
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Amol Shambharkar
    Replies:
    1
    Views:
    5,070
  2. Micheal

    Authentication on Active Directory

    Micheal, Jul 1, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    391
    Micheal
    Jul 1, 2003
  3. Michael
    Replies:
    1
    Views:
    445
  4. ejcosta
    Replies:
    2
    Views:
    913
    Eurico Costa
    Oct 8, 2004
  5. carlos seramos
    Replies:
    2
    Views:
    521
    carlos seramos
    Aug 1, 2003
Loading...

Share This Page