3

The Scenario:
I'm using integrated authentication to grant access to an ASP.net intranet site. When that user accesses the site, certain information is loaded from their active directory profile and made available to them. Also, the site maintains certain information on that user for the web-application that it runs.

What is the best way to both retrieve information from Active Directory (I'm using LDAP), and then furthermore, link active directory profiles to the web application profiles. The web application is using a database of its own, so it's not storing anything in Active Directory.

Do not suggest using the username, as name changes can and do occur, I'm trying to use some form of unique identifier from Active Directory. The unique identifier must be compatible with my SQL Server 2005 database.

IceMage
  • 1,336
  • 7
  • 12
  • This is a two-part answer, I need both the AD Attribute (Likely either objectGUID or objectSID) -=AND=- the best way to programmatically access it. The objectGUID and objectSID attributes are not native data types, they're arrays. – IceMage Nov 18 '09 at 20:11
  • 2
    It almost seems like this may belong on stackoverflow. At least part of your question, how to write your program does belong there. – Zoredache Nov 18 '09 at 20:21

2 Answers2

4

There is a property for user objects (all objects really) in active directory called objectGUID. You can query this from active directory and store it in the database with the user profile. It is entirely unique to that active directory object and will not change if the name changes.

EDIT:

Sample:

Private rootDE As New DirectoryEntry("LDAP://<YourDomainHere>")

Dim ds As New DirectorySearcher(Me.rootDE)
Dim sr As SearchResult

ds.Filter = "(samAccountName=<usernameHere>)"
sr = ds.FindOne()

Dim s As String = Me.GetGUIDString(CType(sr.Properties("objectGUID").Item(0), Byte()))

Dim de As New DirectoryEntry("LDAP://<GUID=" & s & ">")
MessageBox.Show(de.Name)


Private Function GetGUIDString(ByVal guid() As Byte) As String
    Dim index As Integer
    Dim result As New System.Text.StringBuilder(String.Empty)

    For index = 0 To (guid.Length - 1)
        result.AppendFormat("{0:x2}", guid(index))
    Next

    Return result.ToString()
End Function
DCNYAM
  • 1,029
  • 7
  • 14
  • objectGUID and objectSID are stored as an array of Octet Strings, so that makes it extremely difficult to link the two together on this property. How would you suggest overcoming this issue when querying the directory? – IceMage Nov 18 '09 at 19:47
  • The SecurityIdentifier class has a ToString() method that will convert the byte array to it's string representation if you want, and many other neat tricks. – Oskar Duveborn Nov 18 '09 at 20:10
  • objectGUID and objectSID are not the same thing, so don't use them for comparison or linking. The objectGUID can be converted to a string and this string can be used to query AD. See the crude sample I posted in my edit. – DCNYAM Nov 18 '09 at 20:20
  • The sample I posted above was pulled and modified from another sample I put together as a windows app (hence the MessageBox statement). All it does is get a user's properties based on their username, convert the GUID to a string, then use that string to get the same user from AD. The MessageBox simply illustrates that it does indeed get the same object. – DCNYAM Nov 18 '09 at 20:24
3

Do not query LDAP for their domain/userid and SID. That information has already been pulled from AD and is available in their security token in ASP.NET.

Use the SID to link to a profile in the local database. Done.

Here's is an excellent resource you may find useful:

The .NET Developer's Guide to Directory Services Programming by Joe Kaplan

http://www.amazon.com/dp/0321350170

Greg Askew
  • 35,880
  • 5
  • 54
  • 82
  • Exactly what I was looking for. One of those "There's gotta be an easier way to do this" moments. – IceMage Nov 18 '09 at 20:36
  • +1 - If I could, I'd +10 this one. The OS already has plumbing to handle nifty things like security principal name resolution, building tokens that include nested group membership, etc. Leverage the code already in the OS instead of trying to write your own. – Evan Anderson Nov 19 '09 at 17:25