Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / ASP.NET / Security / June 2004

Tip: Looking for answers? Try searching our database.

Problem querying LDAP and/or Active Directory

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Andrew - 23 Jun 2004 23:46 GMT
Hey all,

Working on revamping our Intranet here and making use of the LDPA, Active
Directory, Directory Services, etc. that .Net provides.  I am still fairly
new on this subject, so the problem I have run into I am not sure how to
fix, and really not sure what is causing it.

Here's what is going on (test server - Windows 2003 Server):
I have a page in a folder (under anonymous authentication in IIS6) that has
a link on it that redirects the user to a page in a folder that is set to
use Integrated Windows Authentication but not anonymous.  When redirected,
the IIS security setting forces the user to log in.  Now, in the code of
this "login page" I get the user name via
"Context.User.Identity.Name.ToString" and store that to a Session Variable.
I found a bit of code that queries the LDAP server for the full name of a
user
(http://www.411asp.net/func/content?tree=411asp/tutorial/howto/usermana&id=3
972310) which I have put into a class file.  After storing the user name, I
set the properties and query the LDAP server, using the function of that
class file, for the user's Full Name.  I then save the full name to a
Session Variable as well.  The last thing the page does is redirect back to
the starting page.  Back on the starting page I then display the contents of
the user and full name Session Variables.
The point here is so I can keep my pages set to Anonymous under II6, but if
I can "authenticate" the visitor, then I can have the code-behind page "turn
on" extra features and what not.  Other wise, the page comes up in normal
mode.

My problem...
This all works just fine as long as I am viewing the page from a browser on
the test box.  When I fire up a browser on my machine and navigate to the
page on the test box, it errors out.  The error is occurring on the second
page described above.  I save the error message to a Session Variable and
display that variable's contents back on the first page if an error
occurred.  This is the error I get:

System.Runtime.InteropServices.COMException (0x80072020): An operations
error occurred
  at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
  at System.DirectoryServices.DirectoryEntry.Bind()
  at System.DirectoryServices.DirectoryEntry.get_AdsObject()
  at System.DirectoryServices.DirectorySearcher.FindAll(Boolean
findMoreThanOne)
  at System.DirectoryServices.DirectorySearcher.FindAll()
  at WinAuth.Auth.adsi.GetUserProps() in
c:\inetpub\wwwroot\WinAuth\adsi.vb:line 66
  at WinAuth.index.Page_Load(Object sender, EventArgs e) in
c:\inetpub\wwwroot\WinAuth\login\index.aspx.vb:line 35

I need help here understanding what is going on and why this is happening.
I am thinking it is a permissions issue...in that when I am on the test box,
I can run stuff, but when viewing from a remote box I can't.  Or could it be
trying to query the LDAP box from a remote machine?  I am at a bit of a loss
here.

Your help is greatly appreciated.

-- Andrew

[Code Segment]

** First Page HTML **
----------------------------------------------------------
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="index.aspx.vb"
Inherits="WinAuth.index1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
   <title>index</title>
   <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
   <meta content="Visual Basic .NET 7.1" name="CODE_LANGUAGE">
   <meta content="JavaScript" name="vs_defaultClientScript">
   <meta content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema">
 </HEAD>
 <body style="MARGIN: 0px">
   <form id="Form1" method="post" runat="server">
     <TABLE id="Table1" cellSpacing="1" cellPadding="5" width="100%"
border="0">
       <TR>
         <TD vAlign="top" noWrap align="center" width="125">
           <P><asp:label id="lblStatus" runat="server"
Visible="false"></asp:label><br>
             <asp:linkbutton id="lnkLogin" runat="server"
Visible="false">Please Log In</asp:linkbutton><asp:label id="lblName"
runat="server" Visible="false"></asp:label></P>
         </TD>
         <TD vAlign="top" width="100%">
           <DIV align="center"><asp:label id="Label2" runat="server"
Font-Bold="True" Font-Size="18pt"
Font-Names="Tahoma">Welcome</asp:label></DIV>
           <P align="justify">&nbsp;&nbsp;&nbsp;&nbsp;Lorem ipsum dolor sit
amet,
             consectetuer adipiscing elit. Praesent consequat porta sapien.
Fusce eleifend
             urna sit amet justo. Nunc pellentesque justo vel neque. Donec
nonummy ante vel
             metus. In aliquam vehicula leo. Curabitur metus. Donec arcu
orci, ultrices ac,
             rutrum id, hendrerit vel, tellus. Duis lobortis malesuada
odio. Proin sed enim.
             Proin vitae turpis. Integer mollis. Aenean ac quam. Quisque
vulputate purus sit
             amet risus.
             <br>
           </P>
           <div align="right"><asp:linkbutton id="lnkEdit" runat="server"
Visible="false">Edit Text</asp:linkbutton></div>
         </TD>
       </TR>
     </TABLE>
     <div align="center" style="width:500px;">
       <p align="justify">
         <asp:Label id="lblError" runat="server"
Visible="false"></asp:Label>
       </p>
     </div>
   </form>
 </body>
</HTML>
----------------------------------------------------------

** First Page Code-Behind **
----------------------------------------------------------
Public Class index1
   Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

   'This call is required by the Web Form Designer.
   <System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()

   End Sub
   Protected WithEvents lblStatus As System.Web.UI.WebControls.Label
   Protected WithEvents Label2 As System.Web.UI.WebControls.Label
   Protected WithEvents lnkEdit As System.Web.UI.WebControls.LinkButton
   Protected WithEvents lnkLogin As System.Web.UI.WebControls.LinkButton
   Protected WithEvents lblName As System.Web.UI.WebControls.Label
   Protected WithEvents lblError As System.Web.UI.WebControls.Label

   'NOTE: The following placeholder declaration is required by the Web Form
Designer.
   'Do not delete or move it.
   Private designerPlaceholderDeclaration As System.Object

   Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
       'CODEGEN: This method call is required by the Web Form Designer
       'Do not modify it using the code editor.
       InitializeComponent()
   End Sub

#End Region

   Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
       'Put user code to initialize the page here
       If Not Page.IsPostBack Then
           Select Case UserIsKnown()
               Case False
                   lblStatus.Text = "Anonymous User"
                   lblStatus.Visible = True
                   lnkLogin.Visible = True
               Case True
                   Response.Write("<!-- Session(""FullName""): " &
Session("FullName") & " -->" & ControlChars.NewLine)
                   Response.Write("<!-- Session(""UserName""): " &
Session("UserName") & " -->" & ControlChars.NewLine)
                   Dim FullName As String = Session("FullName")
                   Dim UserName As String = Session("UserName")
                   lblStatus.Text = "Welcome Back!"
                   lblStatus.Visible = True
                   lblName.Text = FullName
                   lblName.Visible = True
                   lnkEdit.Visible = True
           End Select
           If Not Session("Error") Is Nothing Then
               lblError.Text = "<PRE>" & ControlChars.NewLine &
Session("Error") & "</PRE>"
               lblError.Visible = True
           End If
       End If
   End Sub

   Private Function UserIsKnown() As Boolean
       If Session("LoggedIn") Is Nothing Then Session("LoggedIn") = False
       Return (Context.User.Identity.IsAuthenticated Or
Session("LoggedIn"))
   End Function

   Private Sub lnkLogin_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles lnkLogin.Click
       Response.Redirect("/WinAuth/Login/", True)
   End Sub
End Class

----------------------------------------------------------

** Second Page HTML **
----------------------------------------------------------
No HTML was added to default "new page html"
----------------------------------------------------------

** Second Page Code-Behind **
----------------------------------------------------------
Public Class index
   Inherits System.Web.UI.Page
   Private cADSI As New Auth.adsi

#Region " Web Form Designer Generated Code "

   'This call is required by the Web Form Designer.
   <System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()

   End Sub

   'NOTE: The following placeholder declaration is required by the Web Form
Designer.
   'Do not delete or move it.
   Private designerPlaceholderDeclaration As System.Object

   Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
       'CODEGEN: This method call is required by the Web Form Designer
       'Do not modify it using the code editor.
       InitializeComponent()
   End Sub

#End Region

   Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
       'Put user code to initialize the page here
       If Context.User.Identity.IsAuthenticated Then
           Try
               Session("LoggedIn") = True
               Session("UserName") = Context.User.Identity.Name.ToString
               Session("UserName") =
Session("UserName").Substring(Session("UserName").IndexOf("\") + 1)
               With cADSI
                   .AD_ServerName = "pdcdns"
                   .AD_ServiceProvider = "LDAP"
                   .AD_UserName = Session("UserName")
                   Session("FullName") = .GetUserProps()
               End With
               If Session("FullName") = "" Then
                   Session("LoggedIn") = False
               End If
           Catch ex As Exception
               Session("LoggedIn") = False
               Session("Error") = ex.ToString
           End Try
       End If
       Response.Redirect("/WinAuth/", True)
   End Sub

End Class

----------------------------------------------------------

** Class File **
----------------------------------------------------------
'// Example By James Arceri
'// Please send comments or questions to: jarceri@starion.com
'// Code taken from:
http://www.411asp.net/func/content?tree=411asp/tutorial/howto/usermana&id=3972310
Imports System
Imports System.DirectoryServices
Imports System.Text

Namespace Auth

   ' Active Directory Services Interfaces
   Public Class adsi

       Private mvar_AD_ServerName As String
       Private mvar_AD_ServiceProvider As String
       Private mvar_AD_UserName As String

       ' Active Directory server name
       Public Property AD_ServerName() As String
           Get
               Return mvar_AD_ServerName
           End Get
           Set(ByVal Value As String)
               mvar_AD_ServerName = Value
           End Set
       End Property

       ' Active Directory Service provider
       Public Property AD_ServiceProvider() As String
           Get
               Return mvar_AD_ServiceProvider
           End Get
           Set(ByVal Value As String)
               mvar_AD_ServiceProvider = Value
           End Set
       End Property

       ' Active Directory username
       Public Property AD_UserName() As String
           Get
               Return mvar_AD_UserName
           End Get
           Set(ByVal Value As String)
               mvar_AD_UserName = Value
           End Set
       End Property

       ' Gets the info for a specific user
       ' Currently only supports Lightweight Directory Access Protocol
(LDAP) binding
       Public Function GetUserProps() As String
           Try
               Dim strUserName As Array = Split(mvar_AD_UserName, "\", -1,
1)
               Dim strFullName As String
               Dim sPath As String
               Dim objDirEnt As New
DirectoryServices.DirectoryEntry(mvar_AD_ServiceProvider & "://" &
mvar_AD_ServerName)
               Dim objSearcher As New
System.DirectoryServices.DirectorySearcher(objDirEnt)
               Dim objSearchRes As System.DirectoryServices.SearchResult
               objSearcher.Filter = ("(anr=" & strUserName(0) & ")")
               For Each objSearchRes In objSearcher.FindAll
                   sPath = objSearchRes.GetDirectoryEntry.Path
               Next
               objDirEnt.Close()
               objDirEnt.Path = sPath
               strFullName = objDirEnt.Invoke("GET", "Name")
               Return strFullName
           Catch ex As Exception
               Throw
           End Try
       End Function

   End Class

End Namespace
----------------------------------------------------------
Joe Kaplan \(MVP - ADSI\) - 24 Jun 2004 14:08 GMT
Can I see the code for the Directory Services stuff?  It is very likely that
the problem is due to a security context issue. The DirectoryEntry class is
happy to use the current thread security context to bind to AD if you do not
specify credentials, but that may not work in situations where the current
account is a local machine account or an impersonated domain account that
cannot delegate.

There are many useful details here:
http://support.microsoft.com/default.aspx?scid=kb;en-us;329986
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sds/sds/trouble
shooting_authentication_problems_on_asp_pages.asp?frame=true


Joe K.
> Hey all,
>
[quoted text clipped - 12 lines]
> I found a bit of code that queries the LDAP server for the full name of a
> user

(http://www.411asp.net/func/content?tree=411asp/tutorial/howto/usermana&id=3
> 972310) which I have put into a class file.  After storing the user name, I
> set the properties and query the LDAP server, using the function of that
[quoted text clipped - 246 lines]
> '// Please send comments or questions to: jarceri@starion.com
> '// Code taken from:

http://www.411asp.net/func/content?tree=411asp/tutorial/howto/usermana&id=3972310
> Imports System
> Imports System.DirectoryServices
[quoted text clipped - 71 lines]
> End Namespace
> ----------------------------------------------------------

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.