andy44875
asked on
ASP ADSI Authentication Issue - Will work fine for awhile then I am unable to authenticate unless I restart the application poll or IIS.
Has anyone ever experienced any problems authenticating with an ADSI application where after so long it stops responding. I can not track down what is causing the problem. I have a login page that uses the following code. This is running on a windows 2003 domain controller currently. If I put it on a windows 2000 member server I get this error way more often.
Dim oADsObject
Set oADsObject = GetObject(strADsPath)
Dim strADsNamespace
Dim oADsNamespace
strADsNamespace = left(strADsPath, instr(strADsPath, ":"))
set oADsNamespace = GetObject(strADsNamespace)
Set oADsObject = oADsNamespace.OpenDSObject (strADsPat h, strUserName, strPassword, 1)
It authenticates fine, but after so long the login page stops working. If I restart the application pool the page starts to work again. I have a volume of about 500-700 users authenticated at any given time. Should I be authenticating a different way? I use this as a forms based authentication to a portal I built. I use all the error codes to redirect them if the password is expired etc. I thought about trying LDAP authentication, but I ran into problems where it would cache the password or something? If a user logged in and reset their password then logged out they could login with either password...
Any suggestions / help would greatly be appreciated.
Andy
Here is a post on ee that has the same process I am using however I get the issues above.
https://www.experts-exchange.com/questions/20920369/Active-Directory-login-using-ASP-NOT-ASP-Net.html#10612700
Dim oADsObject
Set oADsObject = GetObject(strADsPath)
Dim strADsNamespace
Dim oADsNamespace
strADsNamespace = left(strADsPath, instr(strADsPath, ":"))
set oADsNamespace = GetObject(strADsNamespace)
Set oADsObject = oADsNamespace.OpenDSObject
It authenticates fine, but after so long the login page stops working. If I restart the application pool the page starts to work again. I have a volume of about 500-700 users authenticated at any given time. Should I be authenticating a different way? I use this as a forms based authentication to a portal I built. I use all the error codes to redirect them if the password is expired etc. I thought about trying LDAP authentication, but I ran into problems where it would cache the password or something? If a user logged in and reset their password then logged out they could login with either password...
Any suggestions / help would greatly be appreciated.
Andy
Here is a post on ee that has the same process I am using however I get the issues above.
https://www.experts-exchange.com/questions/20920369/Active-Directory-login-using-ASP-NOT-ASP-Net.html#10612700
ASKER
I am using my own forms based authentication. I use forms based authentication because I check for many variables like if the password has expired etc. I also pass credientials to other applications to make a "single-signon" once they are in my portal. Below is a snapshot of what im doing.
<%
if (not strADsPath= "") then
' bind to the ADSI object and authenticate Username and password
Dim oADsObject
Set oADsObject = GetObject(strADsPath)
Dim strADsNamespace
Dim oADsNamespace
strADsNamespace = left(strADsPath, instr(strADsPath, ":"))
set oADsNamespace = GetObject(strADsNamespace)
Set oADsObject = oADsNamespace.OpenDSObject (strADsPat h, strUserName, strPassword, 1)
domainstring = "NETWORK"
groupstring = "nco-account-admin"
Set GroupObj = GetObject("WinNT://" & DomainString & "/" & GroupString)
For each UserObj in GroupObj.Members
If UserObj.Name = Request.Form("username") then
networktools = "true"
else
end if
Next
domainstring = "NETWORK"
groupstring = "nco-reflection"
Set GroupObj = GetObject("WinNT://" & DomainString & "/" & GroupString)
For each UserObj in GroupObj.Members
If UserObj.Name = Request.Form("username") then
reflection = "true"
else
end if
Next
' we're only bound if err.number = 0
Select Case Err.number
Case 0
session("udistrict") = trim(RS("udistrict"))
session("uall") = trim(RS("uall"))
session("uemis") = trim(RS("uemis"))
session("ufiscal") = trim(RS("ufiscal"))
session("uinfohio") = trim(RS("uinfohio"))
session("usis") = trim(RS("usis"))
session("utac") = trim(RS("utac"))
session("uprodev") = trim(RS("uprodev"))
session("distid") = trim(RS("description"))
Session("title") = title
Session("dirn") = dirn
session("email") = email
session("dbuser") = username
session("username") = strUsername
session("password") = strPassword
session("reflection") = reflection
session("networktools") = networktools
session("nraccess") = trim(RS("nraccess"))
session("nameuser") = nameuser
session("id") = id
session("login") = "True"
call success()
Case -80070775
errFlag = true
call lockedaccount()
Case -2147943726, -2147023570, -2147024810, -2147023677, -2147022694
errFlag = true
call invalidaccount()
Case -2147023565
errFlag = true
call disabledaccount()
Case -2147022987
errFlag = true
call lockedaccount()
Case -2147022989, -2147023541, -2147023688
errFlag = true
call passwordexpired()
Case else
errFlag = true
response.write "If you get this message please report it to support(support at blah):. " & Err.number & " " & Err.Description
end select
err.clear
set oADsObject = nothing
end if
end if
<%
if (not strADsPath= "") then
' bind to the ADSI object and authenticate Username and password
Dim oADsObject
Set oADsObject = GetObject(strADsPath)
Dim strADsNamespace
Dim oADsNamespace
strADsNamespace = left(strADsPath, instr(strADsPath, ":"))
set oADsNamespace = GetObject(strADsNamespace)
Set oADsObject = oADsNamespace.OpenDSObject
domainstring = "NETWORK"
groupstring = "nco-account-admin"
Set GroupObj = GetObject("WinNT://" & DomainString & "/" & GroupString)
For each UserObj in GroupObj.Members
If UserObj.Name = Request.Form("username") then
networktools = "true"
else
end if
Next
domainstring = "NETWORK"
groupstring = "nco-reflection"
Set GroupObj = GetObject("WinNT://" & DomainString & "/" & GroupString)
For each UserObj in GroupObj.Members
If UserObj.Name = Request.Form("username") then
reflection = "true"
else
end if
Next
' we're only bound if err.number = 0
Select Case Err.number
Case 0
session("udistrict") = trim(RS("udistrict"))
session("uall") = trim(RS("uall"))
session("uemis") = trim(RS("uemis"))
session("ufiscal") = trim(RS("ufiscal"))
session("uinfohio") = trim(RS("uinfohio"))
session("usis") = trim(RS("usis"))
session("utac") = trim(RS("utac"))
session("uprodev") = trim(RS("uprodev"))
session("distid") = trim(RS("description"))
Session("title") = title
Session("dirn") = dirn
session("email") = email
session("dbuser") = username
session("username") = strUsername
session("password") = strPassword
session("reflection") = reflection
session("networktools") = networktools
session("nraccess") = trim(RS("nraccess"))
session("nameuser") = nameuser
session("id") = id
session("login") = "True"
call success()
Case -80070775
errFlag = true
call lockedaccount()
Case -2147943726, -2147023570, -2147024810, -2147023677, -2147022694
errFlag = true
call invalidaccount()
Case -2147023565
errFlag = true
call disabledaccount()
Case -2147022987
errFlag = true
call lockedaccount()
Case -2147022989, -2147023541, -2147023688
errFlag = true
call passwordexpired()
Case else
errFlag = true
response.write "If you get this message please report it to support(support at blah):. " & Err.number & " " & Err.Description
end select
err.clear
set oADsObject = nothing
end if
end if
Put these at the end of your code to clean up.
Set oADsObject = Nothing
Set oADsNamespace = Nothing
Set GroupObj = Nothing
At the same time, you may want to use close statements to cleanup also. eg: oADsObject.close (This may only be for LDAP but give it a try)
Set oADsObject = Nothing
Set oADsNamespace = Nothing
Set GroupObj = Nothing
At the same time, you may want to use close statements to cleanup also. eg: oADsObject.close (This may only be for LDAP but give it a try)
ASKER
Slamhound,
I have addded these commands per your suggestion.
Does anyone know if there is a way to monitor the app pool for the amount of sessions that are active? I know I could use the windows preformance monitor, but is there any way to gather more detailed information.
Andy
I have addded these commands per your suggestion.
Does anyone know if there is a way to monitor the app pool for the amount of sessions that are active? I know I could use the windows preformance monitor, but is there any way to gather more detailed information.
Andy
ASKER
Slamhound,
Do you think doing authentication via LDAP is more stable?
I was using LDAP in the mannor below, but noticed some weird things that would occur. If a user reset their password they could get in with their old password and new password. I am wondering if this is just due to the fact a cache stays in effect in active directory for a period of time? It just didn't seem that secure so before troubleshooting I got away from using that method and started using ADSI.
Set dso = GetObject("LDAP:")
Set domain = dso.OpenDSObject("LDAP://N etwork", strUsername, _
strPassword, _
ADS_SECURE_AUTHENTICATION)
'Cleanup:
If (Err.Number <> 0 ) Then
MsgBox("An error has occurred. " & Err.Number)
End If
Set dso = Nothing
Set domain = Nothing
Andy
Do you think doing authentication via LDAP is more stable?
I was using LDAP in the mannor below, but noticed some weird things that would occur. If a user reset their password they could get in with their old password and new password. I am wondering if this is just due to the fact a cache stays in effect in active directory for a period of time? It just didn't seem that secure so before troubleshooting I got away from using that method and started using ADSI.
Set dso = GetObject("LDAP:")
Set domain = dso.OpenDSObject("LDAP://N
strPassword, _
ADS_SECURE_AUTHENTICATION)
'Cleanup:
If (Err.Number <> 0 ) Then
MsgBox("An error has occurred. " & Err.Number)
End If
Set dso = Nothing
Set domain = Nothing
Andy
I've got no comparison info for this one as I've only used LDAP so I can't tell you what's better. But even in the above sample code it would be good to close the dso when you've finished with it. Officially setting it to Nothing means that you blow away all the old stuff but I'm wondering if the aparent caching issues are caused because there's still junk in the old object.
Having said all that, I think I must have abandoned the above code I was talking about. When I went back to look I found that I was using this code to grab the username from their IIS username (but should work fine if they've entered their username in a form too).
Function GetADUsername(Uname)
' trying to get the name of the user from sAMAccountName
Set objRoot = GetObject("LDAP://RootDSE" )
sDomainPath = objRoot.Get("DefaultNaming Context")
Set con = Server.CreateObject("ADODB .Connectio n")
con.provider = "ADsDSOObject"
con.open "Active Directory Provider"
Set Com = Server.CreateObject("ADODB .Command")
Set Com.ActiveConnection = con
Set rstemp = Server.CreateObject("ADODB .Recordset ")
Com.CommandText = "select name, sAMAccountname from 'LDAP://" & m_cOrganUnit & "," & sDomainPath & "' WHERE sAMAccountname='" & Uname & "'"
Set rstemp = Com.Execute
if not rstemp.EOF then
GetADUsername = rstemp.fields("name")
end if
end function
Having said all that, I think I must have abandoned the above code I was talking about. When I went back to look I found that I was using this code to grab the username from their IIS username (but should work fine if they've entered their username in a form too).
Function GetADUsername(Uname)
' trying to get the name of the user from sAMAccountName
Set objRoot = GetObject("LDAP://RootDSE"
sDomainPath = objRoot.Get("DefaultNaming
Set con = Server.CreateObject("ADODB
con.provider = "ADsDSOObject"
con.open "Active Directory Provider"
Set Com = Server.CreateObject("ADODB
Set Com.ActiveConnection = con
Set rstemp = Server.CreateObject("ADODB
Com.CommandText = "select name, sAMAccountname from 'LDAP://" & m_cOrganUnit & "," & sDomainPath & "' WHERE sAMAccountname='" & Uname & "'"
Set rstemp = Com.Execute
if not rstemp.EOF then
GetADUsername = rstemp.fields("name")
end if
end function
ASKER
Slamhound,
This is just going to check if the username exists, but not check that the password is correct right? I need check authentication at this point because I am also checking to see if the account has an expired password or not and redirecting them to a change password utility.
Let me know,
Andy
This is just going to check if the username exists, but not check that the password is correct right? I need check authentication at this point because I am also checking to see if the account has an expired password or not and redirecting them to a change password utility.
Let me know,
Andy
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
You can turn off "Allow Anonymous Users" in IIS and allow them to access the site using their standard Windows login. This is a bit more secure and easier than creating your own login page.
Are you cleaning up (destroying) the objects you've made once you've finished using them? You may just be hitting resource limits.