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?t.../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(Boole an throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_AdsObj ect()
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:lin e 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"> 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: ja*****@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_ServicePr ovider & "://" &
mvar_AD_ServerName)
Dim objSearcher As New
System.DirectoryServices.DirectorySearcher(objDirE nt)
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
----------------------------------------------------------