views:

972

answers:

2

I'm trying to use Integrated Windows Authentication combined with a DirectorySearcher to identify and authenticate the intranet user.

I'd managed to get some fairly simple code that seemed to do the trick, but when I tried on the live server I get the following error:

"The specified domain either does not exist or could not be contacted"

I can't debug the app on the live server so I copied it across to an old development server to test there. When I ran the app normally, it came up with the same error, so the I tried debugging in VS.... except it worked perfectly.

I suspect it's something to do with impersonation or to do with the LDAP call - obviously when it works for the debugger it's hard to be sure what the real problem is.

But I figured one of you guys will be able to point me in the right direction.

Snippets from my authentication class:

Private Function GetUserID() As String
 Dim sID As String = HttpContext.Current.User.Identity.Name
 Return Mid(sID, InStr(sID, "\") + 1)
End Function

Private Function GetDisplayName() As String
 Dim oSearcher As New DirectorySearcher
 Dim oResult As SearchResult
 Dim sName As String = String.Empty

 With oSearcher
  .Filter = String.Format("(SAMAccountName={0})", _UserID)
  .PropertiesToLoad.Add("displayName")
  oResult = .FindOne()
  If Not oResult Is Nothing Then
   sName = oResult.Properties("displayName")(0).ToString()
  End If
 End With

 Return sName
End Function
Private Function GetEmail() As String
 Dim oSearcher As New DirectorySearcher
 Dim oResult As SearchResult
 Dim sEmail As String = String.Empty

 With oSearcher
  .Filter = String.Format("(SAMAccountName={0})", _UserID)
  .PropertiesToLoad.Add("mail")
  oResult = .FindOne()
  If Not oResult Is Nothing Then
   sEmail = oResult.Properties("mail")(0).ToString()
  End If
 End With

 Return sEmail

End Function

Private Function GetGroups() As StringCollection
 Dim oSearcher As New DirectorySearcher
 Dim oResult As SearchResult
 Dim colGroups As New StringCollection
 Dim i As Int16

 With oSearcher
  .Filter = String.Format("(cn=" & _UserName & ")", _UserID)
  .PropertiesToLoad.Add("memberOf")
  oResult = .FindOne()

  If Not oResult Is Nothing Then
   Dim iGroupCount As Int16 = oResult.Properties("memberOf").Count

   For i = 0 To iGroupCount - 1
    colGroups.Add(oResult.Properties("memberOf")(i).ToString())
   Next

  End If
 End With

 Return colGroups
End Function
+1  A: 

Hi,

I once had the same problem and I figured out that the cause of error was the way the url was written.

When using AD and ADSI ensure you are using "UPPER CASE" paths. As I can see from your code you are writing "cn" as lower case. [GetGroups function]

Another way I would try is to ensure that you are making a proper use of the "connectionstring" you are using.

LDAP://CN=" + username + ",OU=" + OU + ",OU=myOU,DC=myDC1,DC=myDC2";

becomes

LDAP://orgname.ad.root/CN=" + username + ",OU=" + OU + ",OU=myOU,DC=myDC1,DC=myDC2";

where "orgname" it's the server name where AD is running on.

Hope this helps.

ntze
You may have been onto something here, but I have had opportunity to check because Jacob has tempted me with his UserPrincipals!
CJM
+1  A: 

I've found it much easier to use the System.DirectoryServices.AccountManagement namespace for this kind of thing, in your case the UserPrincipal class is your friend.

Private Function GetEmail() As String
        Dim pc As PrincipalContext = new PrincipalContext(ContextType.Domain)
        Dim wi As WindowsIdentity = HttpContext.Current.User.Identity
        Dim up As UserPrincipal = UserPrincipal.FindByIdentity(pc, wi.Name)

        Return up.EmailAddress
End Function
Jacob Proffitt
I started off expecting this task to be simple - few lines of code. But it appeared that I *was* going to have to get my hands a lot dirtier - until I discovered System.DirectoryServices.Accountmanagement! I've acheived all that I needed to using this approach and with half the code. Thanks
CJM
Sure thing. I *love* that namespace.
Jacob Proffitt